C/C ++ライン番号
-
27-09-2019 - |
質問
デバッグのために、ライン番号を取得できますか c/C ++コンパイラ? (特定のコンパイラの標準的な方法または特定の方法)
例えば
if(!Logical)
printf("Not logical value at line number %d \n",LineNumber);
// How to get LineNumber without writing it by my hand?(dynamic compilation)
解決
プリプロセッサマクロを使用する必要があります __LINE__
と __FILE__
. 。それらは事前定義されたマクロであり、C/C ++標準の一部です。前処理中、それらはそれぞれ現在の行番号を表す整数を保持している定数文字列と現在のファイル名に置き換えられます。
その他のプレプロセッサ変数:
__func__
:function name(これはの一部です C99, 、すべてのC ++コンパイラがそれをサポートしているわけではありません)__DATE__
:フォームの文字列「mmm dd yyyy」__TIME__
:フォームの文字列「HH:MM:SS」
あなたのコードは次のとおりです。
if(!Logical)
printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);
他のヒント
C ++標準の一部として、使用できるいくつかの事前定義されたマクロが存在します。 C ++標準のセクション16.8は、とりわけ定義されています。 __LINE__
大きい。
__LINE__
: 現在のソースラインのライン番号(小数定数)。
__FILE__
: ソースファイルの推定名(文字文字通り文字列)。
__DATE__
: ソースファイルの翻訳の日付(文字文字列の文字列...)
__TIME__
: ソースファイルの翻訳の時間(文字文字列の文字列...)
__STDC__
: どうにか__STDC__
事前定義されています
__cplusplus
: 名前__cplusplus
C ++翻訳ユニットをコンパイルするときに、値に定義されています199711L
したがって、あなたのコードは次のとおりです。
if(!Logical)
printf("Not logical value at line number %d \n",__LINE__);
同じ動作でマクロを使用できます printf(), 、除き、関数名、クラス、行番号などのデバッグ情報も含まれています。
#include <cstdio> //needed for printf
#define print(a, args...) printf("%s(%s:%d) " a, __func__,__FILE__, __LINE__, ##args)
#define println(a, args...) print(a "\n", ##args)
これらのマクロは同じように動作する必要があります printf(), 、Java Stacktraceのような情報を含む。これがメインの例です:
void exampleMethod() {
println("printf() syntax: string = %s, int = %d", "foobar", 42);
}
int main(int argc, char** argv) {
print("Before exampleMethod()...\n");
exampleMethod();
println("Success!");
}
次の出力が得られます。
main(main.cpp:11)examplemethod()...
Examplemethod(main.cpp:7)printf()syntax:string = foobar、int = 42
Main(main.cpp:13)成功!
使用する __LINE__
(これはダブルアンダースコアラインのダブルアンダースコアです)、プリプロセッサは、それが遭遇したライン番号に置き換えます。
チェックアウト __FILE__
と __LINE__
マクロ
試す __FILE__
と __LINE__
.
あなたも見つけるかもしれません __DATE__
と __TIME__
使える。
ただし、クライアントサイドでプログラムをデバッグする必要があるため、これらの情報を記録する必要がない限り、通常のデバッグを使用する必要があります。
私は今この問題に直面しているので、別の質問にも答えを追加することはできません。 ここ、問題の例のソリューションを提供します。テンプレートを使用して、C ++で関数が呼び出された場所のライン番号のみを取得します。
背景:C ++では、テンプレート引数として非タイプの整数値を使用できます。これは、テンプレート引数としてのデータ型の典型的な使用とは異なります。そのため、このような整数値を機能呼び出しに使用することです。
#include <iostream>
class Test{
public:
template<unsigned int L>
int test(){
std::cout << "the function has been called at line number: " << L << std::endl;
return 0;
}
int test(){ return this->test<0>(); }
};
int main(int argc, char **argv){
Test t;
t.test();
t.test<__LINE__>();
return 0;
}
出力:
関数は行番号で呼び出されました:0
関数は行番号で呼ばれています:16
ここで言及することの1つは、C ++ 11標準では、テンプレートを使用して関数のデフォルトのテンプレート値を指定できることです。 Pre C ++では、非タイプの引数のデフォルト値は、クラステンプレート引数でのみ機能しているようです。したがって、C ++ 11では、上記のように関数定義を複製する必要はありません。 C ++ 11では、const char*テンプレートの引数を持っていることも有効ですが、そのようなリテラルでそれらを使用することはできません __FILE__
また __func__
述べたように ここ.
したがって、C ++またはC ++ 11を使用している場合、これはマクロを使用して呼び出しラインを取得するよりも非常に興味深い代替手段かもしれません。