プリプロセッサ関連のオプション
■-Wcomments

 コメントが矛盾している場合にチェックします.たとえば/*が重複した場合などにワーニングエラーとします.

 リスト16のソースをコンパイルした結果は,以下のとおりです.

〔リスト16〕コメントが矛盾している場合の例test145.c)
/*/*
 *組み込み関数について
 */
#include <stdlib.h>
#include <stdio.h>
main()
{
	int	a;
	a	=	abs(-5);
	printf("%d\n",a);
}

  $ gcc test145.c -Wcomments
  test145.c:1:3: 警告: コメント内に "/*" があります
  $ gcc test145.c
  $

■-Wsystem-headers

 システムヘッダ中に問題があり,ワーニングエラーとなる場合でも通常はメッセージを表示しません.しかし,このオプションを指定することで,すべてのワーニングを表示します.あまり使わないとは思います.

■-MF file

 以下の-M?オプションは,Makefileを作るときに有用なコマンドです.個々のソースの依存関係を明確にします.

 -Mや-MMとともに使用した場合は,指定されたデータファイルに依存情報を書き込みます.

 -MDや-MMDとともに使用した場合,本来のデータファイルではなく,指定されたデータファイルに情報を書き込みます.

 以下のように指定します(リスト17リスト18).

〔リスト17〕依存関係を表示する例
/*
 *依存関係
 */
#include	"test146.h"
int	main()
{
	a	=	1;
	pr01();
	pr02();
	pr03();
	return	0;
}

(a)test146.c
#include	"test146a.h"
void	pr01();
void	pr02();
void	pr03();
int	a;

(b)test146.h
//依存関係の試験
#include	"test146b.h"

(c)test146a.h
//依存関係の試験
#include	"test146c.h"

(d)test146b.h
//依存関係の試験
#include	"test146d.h"

(e)test146c.h
//依存関係の試験

#include <stdio.h>

(f)test146d.h

〔リスト18〕依存関係を出力したリストdepdata_M.txt)
test146.o: test146.c test146.h test146a.h test146b.h test146c.h \
  test146d.h /usr/include/stdio.h /usr/include/features.h \
  /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
  /usr/lib/gcc-lib/i386-redhat-linux/3.2/include/stddef.h \
  /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \
  /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \
  /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
  /usr/lib/gcc-lib/i386-redhat-linux/3.2/include/stdarg.h \
  /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h

  $ gcc -M -MF depdata_M.txt test146.c
  $

 以下のように出力されたデータファイルの内容は,-Mオプションで標準出力に出力されたものと同一です.

  $ gcc -M test146.c
  test146.o: test146.c test146.h test146a.h test146b.h test146c.h \
   test146d.h /usr/include/stdio.h /usr/include/features.h \
   /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
   /usr/lib/gcc-lib/i386-redhat-linux/3.2/include/stddef.h \
   /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \
   /usr/include/bits/sched.h /usr/include/libio.h
/usr/include/_G_config.h \
   /usr/include/wchar.h /usr/include/bits/wchar.h
/usr/include/gconv.h \
   /usr/lib/gcc-lib/i386-redhat-linux/3.2/include/stdarg.h \
   /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
  $

 -MMとともに使用する場合,以下のように指定します.

  $ gcc -MM -MF depdata_MM.txt test146.c

■-MP

 このオプションは分割コンパイルするすべてのソースの依存情報を表示します.-MMや-Mとともに使います.以下では,

-MMとともに使った標準出力をdepdata_MP.txt(リスト23)に書き込んでいます.それぞれのソースをリスト19リスト22に示します.

〔リスト19〕依存関係を表示する例test147.c)
extern	int	a;
int	b;
void	pr01()
{
	b	=	1;
	a	=	10;
	printf("pr01");
}

〔リスト20〕依存関係を表示する例test148.c)
void	pr02()
{
	printf("pr02t146.h");
}

〔リスト21〕依存関係を表示する例(test149.c)
extern	int	b;
#include	"test146.h"
void	pr03()
{
	b	=	0;
	printf("pr03t146.h");
	pr04();

}

〔リスト22〕依存関係を表示する例test150.c)
#include	"test146.h"
void	pr04()
{
	printf("pr04t146.h");
	printf("pr01t146.h");
	a	=	11;

}

〔リスト23〕依存関係を出力したリストdepdata_MP.txt)
test146.o: test146.c test146.h test146a.h test146b.h test146c.h \
  test146d.h

test146.h:

test146a.h:

test146b.h:

test146c.h:

test146d.h:
test147.o: test147.c
test148.o: test148.c
test149.o: test149.c test146.h test146a.h test146b.h test146c.h \
  test146d.h

test146.h:

test146a.h:

test146b.h:

test146c.h:

test146d.h:
test150.o: test150.c test146.h test146a.h test146b.h test146c.h \
  test146d.h

test146.h:

test146a.h:

test146b.h:

test146c.h:

test146d.h:

  $ gcc -MM -MP test146.c test147.c test148.c test149.c test150.c &gt; depdata_MP.txt

 どれがどのソースやヘッダをincludeしているのか,混乱した場合には,これで明確になるでしょう.

■-fpreprocessed

 あまり使用しないオプションだと思いますが,説明します.前処理(preprocessed)されたソースをコンパイルしたいときに使います.

 通常のソースで指定すると,以下のような矛盾が出ます.

  $ gcc test146.c test147.c test148.c test149.c test150.c -fpreprocessed

  test146.c:4: '#' トークンの所で文法エラー
  test146.c:4: 文字列定数の前に 構文解析エラー
  test146.c:8: 警告: データ定義が型や記憶クラスを持っていません
  test146.c:9: 警告: データ定義が型や記憶クラスを持っていません
  test146.c:10: 警告: データ定義が型や記憶クラスを持っていません
  test146.c:11: 構文解析エラー が &quot;return&quot; の前にあります
  test149.c:2: '#' トークンの所で文法エラー
  test149.c:2: 文字列定数の前に 構文解析エラー
  test149.c:6: 文字列定数の前に 構文解析エラー
  test149.c:6: 警告: 組み込み関数 `printf' と型が矛盾します
  test149.c:6: 警告: データ定義が型や記憶クラスを持っていません
  test149.c:7: 警告: データ定義が型や記憶クラスを持っていません
  test149.c:9: 構文解析エラー が '}' トークンの前にあります
  test150.c:1: '#' トークンの所で文法エラー
  test150.c:1: 文字列定数の前に 構文解析エラー
  test150.c:5: 文字列定数の前に 構文解析エラー
  test150.c:5: 警告: 組み込み関数 `printf' と型が矛盾します
  test150.c:5: 警告: データ定義が型や記憶クラスを持っていません
  test150.c:6: 警告: データ定義が型や記憶クラスを持っていません
  test150.c:8: 構文解析エラー が '}' トークンの前にあります
  $

 -Eオプションを指定すると,前処理したソースを標準出力に出力します(連載第4回参照).

 そこで,前処理したソース(リスト24)を-fpreprocessedオプション付きでコンパイルしてみます.

〔リスト24〕前処理したソースリスト(途中省略)(prepro.c)
# 1 "test142.c"
# 1 "<built-in>"
# 1 "<\245\263\245\336\245\363\245\311\245\351\245\244\245\363>"
# 1 "test142.c"




# 1 "/usr/include/stdio.h" 1 3
# 28 "/usr/include/stdio.h" 3
# 1 "/usr/include/features.h" 1 3
# 291 "/usr/include/features.h" 3
# 1 "/usr/include/sys/cdefs.h" 1 3
# 292 "/usr/include/features.h" 2 3
# 320 "/usr/include/features.h" 3
# 1 "/usr/include/gnu/stubs.h" 1 3
# 321 "/usr/include/features.h" 2 3
# 29 "/usr/include/stdio.h" 2 3



      省略

extern char *ctermid (char *__s) ;
# 655 "/usr/include/stdio.h" 3
extern void flockfile (FILE *__stream) ;



extern int ftrylockfile (FILE *__stream) ;


extern void funlockfile (FILE *__stream) ;
# 679 "/usr/include/stdio.h" 3

# 6 "test142.c" 2



main()
{
        int ix;
        int x01 = 100;
        int x02 = 200;

        typeof(typeof(char *) [10]) char_p;
        typeof(typeof(long *) [10]) long_p;

        printf("debug:" "x01=%d\n", x01);
        printf("debug:" "(%d,%d)\n", x01,x02);
        printf("debug:" "(%d,%d,%d行目)\n", x01,x02,20);

        for (ix=0;ix<10;ix++)
        {
                char_p[ix] = (char *)'a'+ix;
                long_p[ix] = (long *)(ix * 1000000L);
        }
        for (ix=0;ix<10;ix++)
        {
                printf("char_p[%d] = %d\n",ix,char_p[ix]);
        }
        for (ix=0;ix<10;ix++)
        {
                printf("long_p=[%d] = %d\n",ix,long_p[ix]);
        }
}

  $ gcc -E test142.c &gt; prepro.c
  $ gcc -fpreprocessed prepro.c -o test142
  $ ./test142test142.c &gt; prepro.c test142
  debug:x01=100
  debug:(100,200)
  debug:(100,200,20行目)
  char_p[0] = 97
  char_p[1] = 98
  char_p[2] = 99
  char_p[3] = 100
  char_p[4] = 101
  char_p[5] = 102
  char_p[6] = 103
  char_p[7] = 104
  char_p[8] = 105
  char_p[9] = 106
  long_p=[0] = 0
  long_p=[1] = 1000000
  long_p=[2] = 2000000
  long_p=[3] = 3000000
  long_p=[4] = 4000000
  long_p=[5] = 5000000
  long_p=[6] = 6000000
  long_p=[7] = 7000000
  long_p=[8] = 8000000
  long_p=[9] = 9000000
  $

 このように,正常に動作しました.

 CPUパワーが低く,プリプロセスに時間がかかるため,プリプロセスを省略して修正し,コンパイルしたいときに使うと有効です.

■-ftabstop=width

 これは,たとえばコンパイラが出力するメッセージにカラム数まで表示されているときに,このソースのタブ幅は何桁かを指定し,きっちりカラム数を表示させるために使います.もっとも,現状ではあまり使わないような気がします.

 リスト25はソースの最後に改行を入れていませんが,このときエラーにはなるものの,10カラム目だということを正確に表示しています.

〔リスト25〕エラーになるソースリストtest151.c)
/*
 *エラーになるソース
 */
int	main()
	{
		int	a		=	1;
		return	0;
	}

  $ gcc test151.c -ftabstop=8
  test151.c:8:10: 警告: ファイル末尾に改行がありません
  $

■-fno-show-column

 このオプションを指定すると,コンパイラが出力するメッセージにカラム数を表示しません.

 先のソースで実行すると以下のようになります.

  $ gcc test151.c -fno-show-column
  test151.c:8: 警告: ファイル末尾に改行がありません
  $

■-no-gcc

 既存のソースで,GCCの場合に特別な処理をしているとして,もしそれが不要な場合,GNU Cではないものとしてコンパイルする方法があります.-no-gccオプションを付けると,__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__はdefinedではないとみなします.

 リスト26のコンパイルおよび実行結果を以下に示します.

〔リスト26〕GNU Cではないとみなしてコンパイルする例test152.c)
/*
 *GNU Cではないとみなしてコンパイルする
 */
int	main()
	{
#if defined __GNUC__
	printf("GNU Cのソースです\n");
#else
	printf("GNU Cのソースではありません\n");
#endif
		int	a		=	1;
		return	0;
	}

  $ gcc test152.c -no-gcc -o test152
  $ ./test152
  GNU Cのソースではありません
  $ gcc test152.c -o test152
  $ ./test152
  GNU Cのソースです
  $

■-remap

 MS-DOSのように非常に短いファイル名しか許されないファイルシステム環境で特別なコードを実行させることができます.

■-$

 通常のGNU Cでは,$の使用を禁じていません.もし,禁じる必要がある際には,このオプションを指定します.リテラル中の$は無視します.

 リスト27のコンパイル結果は以下のようになります.

〔リスト27〕$を使用禁止した例test153.c)
/*
 *$の使用禁止
 */
int	main()
	{
#if defined __GNUC__
	printf("GNU Cのソースです$\n");
#else
	printf("GNU Cのソースではありません$\n");
#endif
		int	$a		=	1;
		return	0;
	}

  $ gcc test153.c
  $ gcc test153.c -$
  test153.c: 関数 `main' 内:
  test153.c:11: プログラムとして逸脱した文字 '$'
  $

Copyright 2003 岸 哲夫

Copyright 1997-2024 CQ Publishing Co.,Ltd.

 

NEW記事内インデックス    連載インデックスはこちら   Interfaceのトップ
C言語の方言を扱うオプション
LINK関連のオプション/メッセージ関連のオプション
◆プリプロセッサ関連のオプション
警告を要求/抑止するオプション