我的项目使用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 ++对象,运算符)。说实话,我不太了解异常,所以上面的代码可能有错误。
答案 0 :(得分:7)
很抱歉在一个晚上给你两个“不”的答案,但是“否”,C ++异常(或类的那些)没有标准的二进制布局。尝试在两个不同的编译器之间使用C ++类/异常会破坏One Definition Rule。
您可以通过仅允许目标文件之间的C API(因为C 具有标准ABI - 应用程序二进制接口)来解决此问题,或者您可以使用一个编译器或编译器编译所有代码其他。不过,我不确定NVCC是否可以使用最后一位。
回答问题编辑:其他一切似乎都有用(C ++对象,运算符):在绝大多数情况下,有许多似乎可以工作的东西。这并不意味着他们不会调用未定义的行为。
答案 1 :(得分:6)
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 :(得分:2)
C ++标准没有指定任何东西的二进制形式,更不用说异常了。没有理由你期望这个工作。