views:

150

answers:

4

hi.

my project uses 2 different C++ compilers, g++ and nvcc (cuda compiler). I have noticed exception thrown from nvcc object files are not caught in g++ object files.

are C++ exceptions supposed to be binary compatible in the same machine? what can cause such behavior?

try { kernel_= new cuda:: Kernel(); }
catch (...) { kernel_= NULL; }

// nvcc object
cuda:: Kernel:: Kernel () {
  ...
  if (! impl_) throw;
}

everything else seems to work (C++ objects, operators). To be honest I do not know exceptions very well so maybe there is mistake in the code above.

A: 

do you have any code snippet for the exception throw and catching?

YeenFei
This really belongs in a comment.....
Billy ONeal
+7  A: 

Sorry to give you two "no" answers in a single night, but "No", C++ exceptions (or classes for that matter) have no standard binary layout. Attempting to use C++ classes/exceptions between two differing compilers breaks the One Definition Rule.

You can work around this by only allowing a C API between the object files (because C has a standard ABI - Application Binary Interface), or you can compile all your code with one compiler or the other. I'm not sure if the last bit is possible with NVCC, however.

In response to question edit: everything else seems to work (C++ objects, operators): There are lots of things that seem to work in the vast majority of cases. That does not mean they do not invoke undefined behavior.

Billy ONeal
I find it rather surprising that most things seem to work. Usually, different compilers purposely have different name mangling schemes, so that you can avoid these problems early, namely at compile time or link time.
Ken Bloom
+1  A: 

The C++ standard doesn't specify the binary form of anything, let alone exceptions. There's no reason you should expect this to work.

Peter Ruderman
Yep. +1 (15chars)
Billy ONeal
+4  A: 

nvcc is a wrapper around a normal c++ compiler, and is basically a preprocessor to convert the cuda syntax into something compilable. You can see what compiler it uses with the --verbose flag.

For instance on my machine compiling

// test.cpp
int main(){return 0;}

with nvcc -v gives

#$ _SPACE_= 
#$ _MODE_=DEVICE
#$ _HERE_=/usr/local/cuda/bin
#$ _THERE_=/usr/local/cuda/bin
#$ TOP=/usr/local/cuda/bin/..
#$ PATH=/usr/local/cuda/bin/../open64/bin:/usr/local/cuda/bin/../bin:/Library/Frameworks/Python.framework/Versions/Current/bin:/Users/me/bin:/usr/local/aspell/bin:/usr/local/noweb:/usr/local/icon/bin:/usr/local/dmd/bin:/usr/local/cuda/bin:/usr/local/sed/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin
#$ INCLUDES="-I/usr/local/cuda/bin/../include"  
#$ LIBRARIES=  "-L/usr/local/cuda/bin/../lib" -lcudart
#$ CUDAFE_FLAGS=
#$ OPENCC_FLAGS=
#$ PTXAS_FLAGS=
#$ gcc -c -x c++ "-I/usr/local/cuda/bin/../include"   -I. -m32 -malign-double -o "/tmp/tmpxft_000010af_00000000-1_test.o" "test.cpp" 
#$ g++ -m32 -malign-double -o "a.out" "/tmp/tmpxft_000010af_00000000-1_test.o"   "-L/usr/local/cuda/bin/../lib" -lcudart

Using the same compiler/flags as listed here should give you binary compatibility

Scott Wales