C++异常二进制兼容性

4

我的项目使用两个不同的C++编译器:g++和nvcc(CUDA编译器)。 我注意到,从nvcc对象文件中抛出的异常在g++对象文件中没有被捕获。

在同一台机器上,C++异常是否应该二进制兼容? 是什么原因导致了这种行为?

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

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

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

3个回答

8
抱歉在同一个晚上给你两个“不”的答案,但是“不”,C++异常(或类)没有标准的二进制布局。在两个不同编译器之间尝试使用C++类/异常会违反One Definition Rule
您可以通过仅允许对象文件之间的C API来解决此问题(因为C有标准的ABI-应用程序二进制接口),或者您可以使用一种编译器编译所有代码。但我不确定最后一部分是否适用于NVCC。
回答问题编辑:其他所有东西似乎都可以工作(C++对象,运算符):在绝大多数情况下,有很多事情看起来都可以工作。这并不意味着它们不会引发未定义的行为。

我发现大多数事情似乎都能正常工作,这让我感到相当惊讶。通常,不同的编译器会有不同的名称修饰方案,以便您可以在编译时或链接时尽早避免这些问题。 - Ken Bloom
@Ken: 这是真的;但是,对于异常处理来说情况并非如此 -- 即编译器在这方面存在相当大的差异。例如,MSVC++ 在 NT 的 SEH 上构建其异常支持,而 GCC 则使用某种形式的基于表格的实现。 - Billy ONeal
我的意思是,我很惊讶大多数东西似乎都能正常工作,因为如果两个不同的编译器以某种方式实现了不同的ABI(无论多么微妙),那么我会期望它们有不同的名称重整方案,以便您不可能错误地组合来自两个不同编译器的二进制文件。请参见http://www.parashift.com/c++-faq-lite/compiler-dependencies.html#faq-38.9。 - Ken Bloom

7

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

使用此处列出的相同编译器/标志应该可以实现二进制兼容性


2

C++标准没有规定任何东西的二进制形式,更不用说异常了。你没有理由指望这会起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接