2013年05月21日(火) [長年日記]
■ インテルコンパイラ13はソースファイルの拡張子に依り動作が変わるみたい
インテルコンパイラを使っていてはまったのでメモ。
#include <iostream> #include <stdexcept> int main() try { throw std::runtime_error("throw !"); } catch (...) { std::cout << "catch !" << std::endl; }
上のC++のソースコードを「icpc (ICC) 13.0.1 20121010」でコンパイルして実行すると
terminate called after throwing an instance of 'std::runtime_error' what(): throw !
と出力された。例外がcatchされていない。
長いこと調べて(調べていたのはもっと巨大なプログラム)分かったのは、ソースファイルの拡張子が .c だと上のようになるということ。拡張子を .cpp にすれば
catch !
と表示される。これが結論。
…なんだけど、拡張子が .c でも、別のオブジェクトファイルをリンクするとcatchしてくれたりする。どんなオブジェクトファイルをリンクしたらそうなるのかは分からなかった。バグっぽい動作に見えるので、最新のインテルコンパイラでは挙動が違うかも。
(追記)
拡張子が .c でも、-xオプションで c++ を指定すれば例外がcatchされるようになった。
% icpc --version icpc (ICC) 13.0.1 20121010 Copyright (C) 1985-2012 Intel Corporation. All rights reserved. % icpc main.c; ./a.out terminate called after throwing an instance of 'std::runtime_error' what(): throw ! % icpc -xc++ main.c; ./a.out catch !
うーん、せめて -xc++ を付けない場合にはコンパイルエラーになってくれればいいのに。
-xオプションはGCCにもあるけれど、GCCの場合はg++を使えば拡張子が.cであってもちゃんと動作する。
% g++ --version g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3) Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. % g++ main.c; ./a.out catch !