C++コンパイラがそれらをサポートしていると仮定すると、ロギングとデバッグの目的で__FILE__
、__LINE__
および__FUNCTION__
を使用する特別な理由notがありますか?
私は主に、ユーザーに誤解を招くデータを与えること(たとえば、最適化の結果として誤った行番号または機能を報告する)を行うか、結果としてパフォーマンスに影響を与えることを懸念しています。
基本的に、__FILE__
、__LINE__
、および__FUNCTION__
をalwaysに信頼させることはできますか?
__FUNCTION__
は非標準であり、__func__
はC99/C++ 11に存在します。その他(__LINE__
および__FILE__
)は問題ありません。
常に正しいファイルと行を報告します(__FUNCTION__
/__func__
の使用を選択した場合は機能します)。最適化はコンパイル時のマクロ展開であるため、要因ではありません。 never何らかの形でパフォーマンスに影響します。
まれに、__LINE__
で指定された行を別の行に変更すると役立つ場合があります。 GNU configureは、元のソースファイルに表示されない行の間にブードゥーを挿入した後、適切な行番号を報告するためにいくつかのテストを行います。例えば:
#line 100
次の行は__LINE__
100で始まります。オプションで、新しいファイル名を追加できます。
#line 100 "file.c"
それはめったに有用ではありません。しかし、それが必要な場合、私が知っている代替手段はありません。実際には、行の代わりにマクロを使用することもできます。これにより、上記の2つの形式のいずれかになります。ブーストプリプロセッサライブラリを使用すると、現在の行を50増やすことができます。
#line BOOST_PP_ADD(__LINE__, 50)
__LINE__
と__FILE__
の使用法について尋ねたので、言及するのが便利だと思いました。 C++から十分な驚きを得ることはありません:)
編集: @Jonathan Lefflerはコメントでさらに良いユースケースを提供しています:
#lineでのメッシングは、ユーザーのソースコードに沿ってユーザーのCコードで報告されたエラーを保持したいプリプロセッサにとって非常に便利です。 Yacc、Lex、および(私にとっては自宅にいる)ESQL/Cプリプロセッサがそれを行います。
参考: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. */
}
個人的には、デバッグメッセージ以外にこれらを使用するのは嫌です。私はそれをしましたが、そのような情報を顧客やエンドユーザーに見せないようにしています。私の顧客はエンジニアではなく、コンピューターに精通していないこともあります。この情報をコンソールに記録することもできますが、先ほど言ったように、しぶしぶデバッグビルドや内部ツールを除きます。ただし、顧客ベースに依存すると思います。
私は常にそれらを使用しています。心配しているのは、ログファイルにIPを配ることだけです。関数名が本当に良い場合は、企業秘密を明らかにするのが簡単かもしれません。デバッグシンボルを使用して出荷するようなもので、見つけるのが難しいだけです。 99.999%のケースでは、悪いことは何もありません。