__FILE__、__LINE__ 実行時エラーが出たファイルと行番号を知りたい


目次に戻る



新世紀初のC言語向けの小枝です。本日初回する実行時のファイル名と行番号を得る方法は、(たぶん)ANSI-C標準機能で便利なのですが、あまりよく知られていない機能です。
 
最近は強力なデバッガがかなり安く手に入る良い時代なのですが、未だに
 
printf("This process is SUCCESS!\n");
等というのをプログラム中にちりばめてデバッグをしている人がたくさんいます。
WindowsやMac等のPC系に比べ、企業で使われていSUN、SGI、HP等のワークステーション系のデバッグソフトは未だに高価(100万位)な為ですが、ちょっと悲しいです。
 
さて、このデバッグ方法には問題があります。例えば、
 
main()
{
    int re;
    re = function1();
    if( re == -1 ){
        printf("Error!\n");
    }
    re = function2();
    if( re == -1 ){
        printf("Error!\n");
    }
    return re;
}
上記のようなプログラムがあったとします。
実行したら"Error!"と画面に表示されました。
エラーはfunction1とfunction2のどちらで表示されたでしょうか。
 
この程度のプログラムでしたら、表示する内容を"function1 Error!"、"function2 Error!"のようにすれば良いのですが、大きなプログラムになりますと、表示内容重複を管理するのが困難になったり、たとえ重複が無くても、画面に表示された文字列がいったいどこで表示されたのかを特定するのが難しくなります。
 
そこで登場するのが、その位置が何というファイルの何行目になるのかをプログラムに埋め込むマクロ __FILE__ 、 __LINE__ です。
 
この二つのマクロは通常の #define で定義したマクロでは無く、コンパイラがコンパイル時に自動的に内容を書き換えてくれる特殊な物になります。
 
言葉で言っても理解しづらいのでとりあえず、下のプログラムを実行してみましょう。
テストプログラム:test.c
#include <stdio.h>

main()
{
    printf("filename = %s , line = %d\n",__FILE__,__LINE__ );

    printf("filename = %s , line = %d\n",__FILE__,__LINE__ );

    return 0;
}

実行結果
filename = test.c , line = 5
filename = test.c , line = 7

もちろんソースファイル名を変更してコンパイルし直せば、filenameの部分は別の名前になります。
 
注意!
__FILE__ __LINE__ の使用で、一つだけ注意点があります。それは、__FILE__ __LINE__ を毎回付けるのが面倒だからと言って下記の様に関数化してはいけません。
おそらく意図した結果が得られない関数
void printLog( char *msg )
{
    printf("%s,%d:%s\n",__FILE__,__LINE__,msg);
}
こうしてしまうと、__FILE__と__LINE__は上記の関数が記述されている位置を指してしまいます。
もし、上記のような使い方がしたいのであればマクロを使います。
正しい使い方
#define printLOG( msg ) printf("%s,%d:%s\n",__FILE__,__LINE__,msg)
 



目次に戻る