1 つのオプションは、C ファイルを完全に前処理し、その中のすべてのマクロを展開してから、前処理された結果のファイルをコンパイルすることです。
たとえば、次の単純な C プログラムについて考えてみましょう。
// file: prep.c
#include <stdio.h>
#define MY_BIG_MACRO \
int i; \
printf("integers from 0 to 9:\n"); \
for (i = 0; i < 10; i++) \
printf("%d ", i); \
printf("\n");
int main(void)
{
MY_BIG_MACRO
return 0;
}
コンパイルして、一時ファイル (前処理されたソース コードを含む) を保存します。
gcc -Wall -O2 -g -std=c99 prep.c -o prep.exe -save-temps
これにより、前処理されたバージョンのprep.c
, prep.i
(簡潔にするために短縮されています)が得られます。
# 1 "prep.c"
# 1 "C:\\MinGW\\msys\\1.0\\home\\Alex//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "prep.c"
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.6.2/../../../../include/stdio.h" 1 3
...
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (const wchar_t * __restrict__,
const wchar_t * __restrict__, __gnuc_va_list);
# 3 "prep.c" 2
# 11 "prep.c"
int main(void)
{
int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) printf("%d ", i); printf("\n");
return 0;
}
ここで、# 行を削除します。いずれにせよ、それらが残っていると、デバッグ情報に影響します。驚いたことに、これは、マクロが で展開されて表示されないことを意味しgdb
ます。
ありがたいことに、grep
助けてくれます(私はgrepのプロではないので、パラメーターが正しいかどうかを確認してください。ただし、MinGW x86を搭載したWindowsで機能するようです):
grep ^[^\#].*$ prep.i > prepi.c
prep.i
これにより、 inの削除されたバージョンが得られますprepi.c
。
typedef unsigned int size_t;
typedef short unsigned int wchar_t;
typedef short unsigned int wint_t;
...
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (const wchar_t * __restrict__,
const wchar_t * __restrict__, __gnuc_va_list);
int main(void)
{
int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) printf("%d ", i); printf("\n");
return 0;
}
これでコンパイルできます:
gcc -Wall -O2 -g -std=c99 prepi.c -o prepi.exe
そしてそれを実行しgdb
ます:
gdb prepi.exe
次のコマンドを発行します。
b main
r
l
これにより、アプリが実行main()
され、到達したブレークポイントに関連するソース コードが一覧表示されます。
(gdb) b main
Breakpoint 1 at 0x40643f: file prepi.c, line 184.
(gdb) r
Starting program: C:\MinGW\msys\1.0\home\Alex\prepi.exe
[New Thread 7340.0x20c4]
Breakpoint 1, main () at prepi.c:184
184 int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) pri
ntf("%d ", i); printf("\n");
(gdb) l
179 const wchar_t * __restrict__, __gnuc_va_list);
180 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (c
onst wchar_t * __restrict__,
181 const wchar_t * __restrict__, __gnuc_va_list);
182 int main(void)
183 {
184 int i; printf("integers from 0 to 9:\n"); for (i = 0; i < 10; i++) pri
ntf("%d ", i); printf("\n");
185 return 0;
186 }
(gdb)
ご覧のとおり、マクロ本体がプレーン ビューになりました。
ここでの小さな問題の 1 つは、複数行のマクロ ( で続くマクロ\
) が 1 行に展開されることです。それらを複数の行に展開するオプションは見つかりませんでしたが、手動で行うことができます。