Search code examples
c++cudalinker-errorsextern

How to use extern for declaring/defining global variable in C++ and CUDA


I have the following code structure composed of one .cpp, one .cu and one .hxx

UTILITIES.hxx

#ifndef UTILITIES_HXX
#define UTILITIES_HXX

namespace B{

extern int doors;
}

FILE2.cu

#include "utilities.hxx"

namespace A {

int foo (){
    switch(B::doors){
    //do something
    }
}
}

FILE3.cxx

#include "utilities.hxx"

namespace B{

int doors=-1;

class Vehicle{
public:
  void operation() {
      doors++;
      A::foo();
      doors++;
      A::foo();
  }
}
}

I am declaring the doors variable as extern in the header and I am defining it in the .cxx file. So after that, the second .cpp should be able to use it. However I am getting the following error when linking:

/usr/bin/ld: ../src/libapp.a(FILE2.cu.o): in function A::foo(void)': /MYPATH/FILE2.cu:19: undefined reference to B::doors'

What am I doing wrong? Actually the foo function in the FILE2.cu is a normal C++ function, no CUDA involved at all.


Solution

  • missing #endif, missing return statement, no prototype for A::foo(), missing semicolon

    These changes seem to work for me:

    $ cat utilities.hxx
    #ifndef UTILITIES_HXX
    #define UTILITIES_HXX
    
    namespace B{
    
    extern int doors;
    }
    #endif
    $ cat file2.h
    
    namespace A {
    
    int foo ();
    }
    $ cat file2.cu
    #include "utilities.hxx"
    
    namespace A {
    
    int foo (){
        switch(B::doors){
        //do something
        }
        return 0;
    }
    }
    $ cat file3.cpp
    #include "utilities.hxx"
    #include "file2.h"
    namespace B{
    
    int doors=-1;
    
    class Vehicle{
    public:
      void operation() {
          doors++;
          A::foo();
          doors++;
          A::foo();
      }
    };
    }
    
    $ nvcc -shared file2.cu file3.cpp -Xcompiler -fPIC
    $ nvcc -lib file2.cu file3.cpp 
    $ 
    

    I can only work with what you have shown.