C ++ исключения бинарной совместимости - PullRequest
3 голосов
/ 12 апреля 2010

мой проект использует 2 разных компилятора C ++, g ++ и nvcc (cuda compiler). Я заметил исключение, генерируемое из объектных файлов nvcc, которые не попадают в объектные файлы g ++.

Предполагается, что исключения C ++ должны быть двоично-совместимыми на той же машине? что может вызвать такое поведение?

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

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

все остальное работает (объекты C ++, операторы). Честно говоря, я не очень хорошо знаю исключения, так что, возможно, в приведенном выше коде есть ошибка.

Ответы [ 3 ]

7 голосов
/ 12 апреля 2010

Извините, что даю вам два ответа "нет" за одну ночь, но исключения "Нет", C ++ (или классы в этом отношении) не имеют стандартной двоичной структуры. Попытка использовать классы / исключения C ++ между двумя разными компиляторами нарушает правило One Definition .

Вы можете обойти эту проблему, разрешив только API C между объектными файлами (поскольку C имеет стандартный ABI - двоичный интерфейс приложения), или вы можете скомпилировать весь свой код с помощью одного компилятора или другого , Однако я не уверен, что последний бит возможен с NVCC.

В ответ на редактирование вопроса: все остальное работает (объекты C ++, операторы) : есть множество вещей, которые кажутся работающими в подавляющем большинстве случаев. Это не значит, что они не вызывают неопределенного поведения.

6 голосов
/ 12 апреля 2010

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 голосов
/ 12 апреля 2010

Стандарт C ++ не определяет двоичную форму чего-либо, не говоря уже об исключениях. Нет причин ожидать, что это сработает.

...