C++;二进制兼容性例外 我的项目使用2种不同的C++编译器,G++和NVCC(CUDA编译器)。 我注意到从nvcc对象文件抛出的异常在g++对象文件中没有被捕获 C++中的异常是否应该是二进制兼容的? 什么会导致这种行为 try { kernel_= new cuda:: Kernel(); } catch (...) { kernel_= NULL; } // nvcc object cuda:: Kernel:: Kernel () { ... if (! impl_) throw; }

C++;二进制兼容性例外 我的项目使用2种不同的C++编译器,G++和NVCC(CUDA编译器)。 我注意到从nvcc对象文件抛出的异常在g++对象文件中没有被捕获 C++中的异常是否应该是二进制兼容的? 什么会导致这种行为 try { kernel_= new cuda:: Kernel(); } catch (...) { kernel_= NULL; } // nvcc object cuda:: Kernel:: Kernel () { ... if (! impl_) throw; },c++,exception,binary-compatibility,C++,Exception,Binary Compatibility,其他一切似乎都正常(C++对象、运算符)。老实说,我不太了解异常,所以上面的代码可能有错误。 < P>对不起,在一个晚上给你两个“不”的答案,但是“不”,C++异常(或这一类)没有标准的二进制布局。试图在两个不同编译器之间使用C++类/异常会打破.< /P> 您可以通过只允许在对象文件之间使用C API来解决这个问题(因为C有一个标准的ABI应用程序二进制接口),或者您可以使用一个或另一个编译器编译所有代码。但是,我不确定最后一位是否可以使用NVCC 在回答问题时,编辑:其他一切似乎都正常工作(

其他一切似乎都正常(C++对象、运算符)。老实说,我不太了解异常,所以上面的代码可能有错误。

< P>对不起,在一个晚上给你两个“不”的答案,但是“不”,C++异常(或这一类)没有标准的二进制布局。试图在两个不同编译器之间使用C++类/异常会打破.< /P> 您可以通过只允许在对象文件之间使用C API来解决这个问题(因为C有一个标准的ABI应用程序二进制接口),或者您可以使用一个或另一个编译器编译所有代码。但是,我不确定最后一位是否可以使用NVCC


在回答问题时,编辑:其他一切似乎都正常工作(C++对象、运算符):在绝大多数情况下,有很多事情似乎正常工作。这并不意味着它们不调用未定义的行为。

< P> C++标准没有指定任何二进制形式,更不用说例外。你没有理由期望这能起作用。

nvCC是一个围绕普通C++编译器的包装器,基本上是一个预处理器,用来将CUDA语法转换成可编译的东西。您可以通过

--verbose
标志查看它使用的编译器

例如在我的机器上编译

// test.cpp
int main(){return 0;}
使用
nvcc-v
给出

#$ _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

使用与这里列出的相同的编译器/标志应该可以提供二进制兼容性

我发现大多数事情似乎都能正常工作,这相当令人惊讶。通常,不同的编译器有目的地使用不同的名称损坏方案,以便您可以尽早避免这些问题,即在编译时或链接时。@Ken:这是真的;但异常处理情况并非如此——也就是说,因为这是编译器差异很大的地方之一。例如,MSVC++在NT的SEH之上构建了它的异常支持,而GCC使用某种形式的基于表的实现。我的意思是,我很惊讶大多数东西似乎都能工作,因为如果两个不同的编译器以某种方式实现不同的ABI(无论多么微妙),然后,我希望它们有目的地使用不同的名称损坏方案,这样您就不可能犯组合来自两个不同编译器的二进制文件的错误。看见