web-dev-qa-db-ja.com

C / C ++の行番号

デバッグの目的で、[〜#〜] 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)
98
Betamoo

プリプロセッサマクロ__LINE__および__FILE__を使用する必要があります。これらは事前定義されたマクロであり、C/C++標準の一部です。前処理中に、それぞれ現在の行番号を表す整数を保持する定数文字列と現在のファイル名に置き換えられます。

その他のプリプロセッサ変数:

  • __func__:関数名(これは 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__);
162
Julien Hoarau

C++標準の一部として、使用可能な定義済みマクロがいくつか存在します。 C++標準のセクション16.8では、とりわけ、__LINE__ 大きい。

__LINE__現在のソース行の行番号(10進定数)。
__FILE__ソースファイルの推定名(文字列リテラル)。
__DATE__ソースファイルの翻訳日(文字列リテラル...)
__TIME__ソースファイルの翻訳時間(文字列リテラル...)
__STDC__かどうか__STDC__は事前定義されています
__cplusplus名前__cplusplusは、C++翻訳単位をコンパイルするときに値199711Lに定義されます。

したがって、コードは次のようになります。

if(!Logical)
  printf("Not logical value at line number %d \n",__LINE__);
61
Brian R. Bondy

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スタックトレースのような情報を含みます。メインの例を次に示します。

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()構文:string = foobar、int = 42
main(main.cpp:13)成功!

18

つかいます __LINE__(これは二重アンダーラインLINE二重アンダースコアです)、プリプロセッサはそれを検出された行番号に置き換えます。

11
meagar

チェックアウト __FILE__および__LINE__マクロ

9
Anton

__FILE__および__LINE__
また、__DATE__および__TIME__便利。
クライアント側でプログラムをデバッグする必要があるため、これらの情報を記録する必要がない限り、通常のデバッグを使用する必要があります。

4
Sanctus2099

私も今この問題に直面しており、別のしかし有効な質問に答えを追加することはできません here 、この関数は、テンプレートを使用して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 Standardでは、テンプレートを使用して関数のデフォルトのテンプレート値を指定できることです。 C++ 11以前では、非型引数のデフォルト値はクラステンプレート引数でのみ機能するようです。したがって、C++ 11では、上記のように重複した関数定義を持つ必要はありません。 C++ 11では、const char *テンプレート引数を持つことも有効ですが、 here のように__FILE____func__などのリテラルで使用することはできません。

したがって、最終的にC++またはC++ 11を使用している場合、これは呼び出しラインを取得するためにマクロを使用するよりも非常に興味深い選択肢になる可能性があります。

1
John Doe