2009-02-27 19 views
114

仮定すると、あなたのC++コンパイラがそれらをサポートしていることを、ログとデバッグの目的のために__FILE____LINE____FUNCTION__を使用するには、いずれかの特定の理由ないはありますか?__FILE__、__LINE__と__FUNCTION__の利用++

私は主に、間違った行番号や機能を最適化の結果として報告するなど、誤解を招くようなデータをユーザに与えることや、結果としてパフォーマンスが低下することに懸念しています。

基本的に、私は正しいことを行う常に__FILE____LINE____FUNCTION__を信頼できますか?

+0

__LINE__は正しいことを行う必要があります。私はそれを__PRETTY_FUNCTION__を含む広範囲に使用してきました。 ...しかし...まあ、私はちょうど__LINE__があるコードを見ています。おそらく、try/catch例外処理のためのcatchブロック内にあるからです。 –

+2

関連:[定義済みのマクロのgccリファレンス](http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html) –

答えて

140

__FUNCTION__は非標準であり、__func__がC99/C++ 11に存在します。他のもの(__LINE____FILE__)は問題ありません。

これは常に適切なファイルと行を表示します(また、__FUNCTION__/__func__を使用する場合は機能します)。最適化は、コンパイル時のマクロ展開であるため、非ファクタです。 決して効果のパフォーマンスは決してありません。

+2

'__func__'はC++で問題になります。 C99では、デフォルトの引数などについては言及していませんが、 '__func__'がC++でどのように動作すべきかはあまり明らかではありません。 – wilhelmtell

+3

@thr:良い点を挙げている間。私は '__func__'がc99ではなくC++に存在することをはっきりと知っていました。それにもかかわらず、私はC++で '__func__'を合理的に実装すると、名前が変更されるだけです。私はコンパイラライターではないので、実際に私の呼び出しではありません。 –

+0

'__FUNCTION__'をサポートしていないコンパイラは?最近のgcc以外のコンパイラはこれをマクロではなく変数として扱いますか? – basin

7

個人的には、これらのメッセージをデバッグメッセージ以外に使用することは嫌です。私はそれをしましたが、私はそのような情報を顧客やエンドユーザーに示さないようにしています。私の顧客はエンジニアではなく、コンピュータに精通していないこともあります。私はコンソールにこの情報を記録するかもしれませんが、私が言ったように、デバッグビルドや内部ツールを除いて、不本意ながら。あなたが持っている顧客基盤に依存していると思います。

+21

"私はこの情報をコンソールに記録するかもしれません" - またはもっと良いことには:ファイルにログを記録して、何か問題が起きた場合に顧客にあなたに送るように頼むことができます。 – Christoph

30

まれに、__LINE__で指定された行を別のものに変更すると便利です。私はGNU configureが元のソースファイルに現れない行の間にいくつかのブードーを挿入した後、適切な行番号を報告するテストがあることを知っています。たとえば:

#line 100 

は、次の行は、あなたが、必要に応じてそれが唯一のまれ便利です

#line 100 "file.c" 

新しいファイル名を追加することができます__LINE__ 100で始まるようになります。しかし、それが必要な場合は、私が知っている選択肢はありません。実際には、行の代わりに、上記の2つの形式のいずれかになるマクロも使用できます。ブーストプリプロセッサライブラリを使用して、あなたが50で現在の行をインクリメントすることができます

#line BOOST_PP_ADD(__LINE__, 50) 

私はあなたが__LINE____FILE__の使用について尋ねているので、それはそれを言及するのに便利だと思いました。 @ジョナサンレフラーは、コメント欄でいくつかのより良いユースケースを提供します:#行をいじり

は、その前のプロセッサのために非常に有用である一つは、C++ :)

編集のうち、十分な驚きを得ることはありませんユーザのソースファイルに沿ってユーザのCコードにエラーを報告したい。 Yacc、Lex、(私にとっては自宅で)ESQL/Cプリプロセッサがそうしています。

22

FYI:g ++は非標準の__PRETTY_FUNCTION__マクロを提供します。今まで私はC99について知りませんでした__func__(感謝のエヴァン!)。私はまだ余分なクラスのスコープのために利用可能なときに__PRETTY_FUNCTION__を好むと思います。

PS:私はそれらのすべての時間を使用し

static string getScopedClassMethod(string thePrettyFunction) 
{ 
    size_t index = thePrettyFunction . find("("); 
    if (index == string::npos) 
    return thePrettyFunction; /* Degenerate case */ 

    thePrettyFunction . erase(index); 

    index = thePrettyFunction . rfind(" "); 
    if (index == string::npos) 
    return thePrettyFunction; /* Degenerate case */ 

    thePrettyFunction . erase(0, index + 1); 

    return thePrettyFunction; /* The scoped class name. */ 
} 
+0

\ _ \ _ PRETTY_FUNCTION \ _ \ _。非常に便利! – Maverobot

4

。私が心配するのは、ログファイルにIPを渡すことだけです。あなたの関数名が本当に良ければ、営業秘密を簡単に明らかにするかもしれません。これは、デバッグシンボルを使った出荷のようなもので、見つけにくいものです。 99.999%のケースでは悪いことはありません。

+0

育ちやすいポイント。実行可能ファイルからすべての文字列のようなデータを抽出する 'strings'ユーティリティを使用してこの情報を抽出するのは簡単です。圧縮された実行可能ファイルも抽出できます。お客様のサイトに送信する内容に非常に注意してください。多くの場合、競合他社は実行する必要がないにもかかわらず、実行可能ファイルに手を差し伸べることができます。 – Marty

関連する問題