事前定義マクロとプラグマ 解答ページ | Programming Place Plus C言語編 第29章

トップページC言語編第29章

問題①

問題① プログラムの実行直後に、そのソースファイルをコンパイルしたときの日付・時刻を出力してみてください。


たとえば、次のようになります。

#include <stdio.h>

int main(void)
{
    printf("BuildTime: %s %s\n", __DATE__, __TIME__);

    puts("*****");
}

実行結果:

BuildTime: Sep 20 2009 16:12:26
*****

日付と時刻を、プログラムの実行時に判断しているわけではないことがポイントです。__DATE__ も __TIME__ も、プリプロセスで処理されているので、ビルドが終わった時点では確定済みです。そのため、実行するたびに結果が変わるようなことはありません。

【上級】__DATE__ と __TIME__ を使っていると、同じソースファイルをコンパイルしても、異なるオブジェクトファイルが生成されることに注意してください。このため、実行可能ファイルも異なるものになります。たとえば複数のプログラマーで開発を行っている場合、ほかの作業者がビルドした結果とは異なるものが生成されることになります。

問題②

問題② ソースコード上のある地点で、ソースファイルの名前と行数を出力できるデバッグ関数を次のように作成しました。しかし、この関数には実用上の問題があります。問題点を指摘してください。

void print_log(void)
{
    printf("File: %s   Line: %d\n", __FILE__, __LINE__);
}


実用上の問題を想像できるでしょうか? 実際に使ってみるとよく分かります。

#include <stdio.h>

void print_log();

int main(void)
{
    puts("aaaaa");
    print_log();
    puts("bbbbb");
    print_log();
    puts("ccccc");
}

void print_log(void)
{
    printf("File: %s   Line: %d\n", __FILE__, __LINE__);
}

実行結果:

aaaaa
File: c:\main.c   Line: 18
bbbbb
File: c:\main.c   Line: 18
ccccc

__FILE__ や __LINE__ は、その記述がある場所のファイル名と行数に置換されるので、print_log関数のように関数化してしまうと、print_log関数の内側の行数にしかなりません。実用上、本当に出力して欲しい情報は、print_log関数を呼び出した位置の行数のはずですから、これでは問題があります。

解決策は、関数にするのをやめて、関数形式マクロで実装することです。

#include <stdio.h>

#define PRINT_LOG()    printf("File: %s   Line: %d\n", __FILE__, __LINE__);

int main(void)
{
    puts("aaaaa");
    PRINT_LOG();
    puts("bbbbb");
    PRINT_LOG();
    puts("ccccc");
}

実行結果:

aaaaa
File: c:\main.c   Line: 8
bbbbb
File: c:\main.c   Line: 10
ccccc

これなら、PRINT_LOGマクロが展開された位置に __FILE__ と __LINE__ も置かれるので、呼び出した場所のファイル名と行数が出力できます。

問題③

問題③ 自分の使っているコンパイラに用意されている pragma指令について調べてください。


使っているコンパイラが Visual Studio なら、Microsoft のドキュメントを確認します。Microsoft のドキュメントは、Microsoft Docs という Webサイトにあります。ここには、多数ある Microsoft 製品のドキュメントが集められているので、そこから絞り込んでいくか、検索機能を活用します。あるいは、Google検索などで「VisualStudio pragma」などを検索してみるのでもいいでしょう。

Visual Studio のプラグマについては、「プラグマ ディレクティブと __ pragma キーワードと _Pragmaキーワード」というページにまとめられています。Microsoft Docs の日本語訳はかなり酷いものなので、英語で読むか(画面右上に「英語で読む」というボタンがあります)、英語ページを Google翻訳などで日本語訳しなおして読む方がいいかもしれません。


参考リンク


更新履歴

’2018/3/5 全面的に文章を見直し、修正を行った。

’2009/9/20 新規作成。



第29章のメインページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る