人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

C/C++言語について教えてください。
inline void __DUMMY_TRACE__(...) {}
この記述はコンパイラで最適化されると全て記述が取っ払われるのでしょうか?(実効モジュール上に記述が存在しなくなる?)
たとえば引数部分に++等の『値を加工するマクロ』や、『関数』が指定された場合でも、記述が無くなってしまうのでしょうか?
_DUMMY_TRACE(fun1(), func2(), a++){}
といった記述でも、最適化されて記述が取り除かれるのでしょうか?

●質問者: akunaki
●カテゴリ:ビジネス・経営 コンピュータ
✍キーワード:C/C++ void コンパイラ マクロ モジュール
○ 状態 :終了
└ 回答数 : 5/5件

▽最新の回答へ

1 ● dev_zer0
●200ポイント

http://www.hatena.ne.jp/1123005817

人力検索はてな - C,C++のTRACEをリリースビルドで無効化する定義(よくTRACE.h等に記述されている内容)について、教えてください。 inline void __DUMMY_TRACE__(...) {} #define TRACE 1 ? ..

上記URLの質問を踏まえて回答します。

結論から言うとリリースビルドでコンパイルすれば

_DUMMY_TRACE(fun1(), func2(), a++);

といった記述も取っ払われます。


よって、トレースや、assertなどのマクロ引数では副作用が発生する関数呼び出しや、計算は行うことは厳禁です。

デバッグモードでは上手く動くのにリリースビルドでは動かないという悲惨な結果になります。

# もっと悲惨な結果はたまたま動いて、たまに落ちるですけど。

◎質問者からの返答

結論から言うとリリースビルドでコンパイルすれば

_DUMMY_TRACE(fun1(), func2(), a++);

といった記述も取っ払われます。

これは、言語仕様でしょうか?環境依存でしょうか?


2 ● dev_zer0
●200ポイント

http://www.hatena.ne.jp/awindow?qid=1123210057

URLはダミーです。

> これは、言語仕様でしょうか?環境依存でしょうか?

言語仕様ではTRACEはC/C++では定義されていません。

よって、TRACEが定義されいること、そのTRACEがどう振る舞うかは処理系依存です。


VC++においてはTRACEは最適化されて、記述が取り除かれます。

BC, gccは試してませんが、

inline void __DUMMY_TRACE__(...) {}

#define TRACE 1 ? ((void) 0) : __DUMMY_TRACE__

ならば、__DUMMY_TRACE__関数に絶対に到達しないので、最適化によって取り除かれる可能性は高いと考えています。


3 ● merida
●200ポイント

http://seclan.dll.jp/c99d/c99d07.htm#dt19990802

?v???O???~???O???? C ??V?@?\

C99によるCの拡張機能

> inline 定義はコンパイラに対するヒントであり、コンパイラは必ずしも高速呼び出しコードを生成するとは限りません。


inline展開されるかされないかはコンパイラ依存の様です。

また、処理系によっても異なるものと思われます。

http://www.linux.or.jp/JM/html/GNU_gcc/man1/gcc.1.html

Manpage of GCC

gccのマニュアル日本語訳


また、インライン展開されるか否かは最適化オプションによっても変わります。

gccでは-Sオプションでアセンブラコードが出力されるので、

> gcc -O0 -S test.c

> gcc -O2 -S test.c

の2つの出力ファイルを見比べるとその違いがわかると思います。

(前者はcallでinline関数にジャンプするのに対し、

後者はcallおよびinline関数名がなくなっているはずです。)

◎質問者からの返答

納得できました。情報有り難う御座います。


4 ● terra5
●200ポイント

http://www.windriver.com/japan/products/wind_river_compiler/comp...

先進のコンパイラ最適化技術

最適化は無駄な処理を省くとか、より高速に処理できるように変形するだけです。


一般的なコンパイラの話であれば、副作用がある処理が取り除かれることはありません。

もしあれば、通常は最適化のバグです。

最適化は無駄を省くだけで、論理的な結果が変わるようなものは最適化でありません。


_DUMMY_TRACE(fun1(), func2(), a++){}

もfun1,func2の呼び出しとa++は通常は残ると思いますが、a++がローカル変数でこの後一度も参照されない、fun1,fun2が内容が空であるとか、実行結果が全く外部に反映されることが無い(変数などが全く変化が無いか、ローカル変数等が変わるだけで外部には一切結果が反映されない)場合は、削除される可能性があります。必要なのは残りますから一部だけ無くなる可能性もあります。


記述が取っ払われるというのは意味があいまいですが、inlineですから _DUMMY_TRACE_という関数は存在しなくなりますから、

そういう意味では_DUMMY_TRACE_そのものは存在しないとも言えますね。


ところで、自分で試してみましたか?

◎質問者からの返答

いろいろ疑問あったので、コンパイルしてみました。(VC++のコンパイルオプションで、プリプロセッサ処理後のファイル出してみました。)

情報有り難う御座います。


5 ● fruitage
●200ポイント

http://www.hatena.ne.jp/1123210057#

人力検索はてな - C/C++言語について教えてください。 inline void __DUMMY_TRACE__(...) {} この記述はコンパイラで最適化されると全て記述が取っ払われるのでしょうか?(実効モジュー..

URLはダミーです。

まず、__DUMMY_TRACE__という関数名ですが、これは下線で始まり下線が続いていますので「予約済み識別子」にあたります。__DUMMY_TRACE__関数が処理系によって提供されている場合を除き、その動作は未定義になります。つまり、コンパイルできるかどうかも含めて、何が起こるかは分かりません。

◎質問者からの返答

情報有り難う御座いました。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ