Last Update 2021/09/11
-Wmultistatement-macros
if、else、for、switch、whileのブロック内に含まれているように見える安全ではない複数ステートメントのマクロについての警告
テスト概要
オプション無し、-Wmultistatement-macros、-Wallの各オプションを使用した際の警告出力例
実行環境
GCC-8.2.0
GNU C Library 2.28
GNU Binutils 2.31.1
GNU C Library 2.28
GNU Binutils 2.31.1
コード例・出力内容中の表記
・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
使用ファイル
sample.c
#include <stdio.h>
/* 複数ステートメントマクロ */
#define MACRO_SAMP1 n1++; n2++;
/* for文の中に複数ステートメントのマクロ */
#define MACRO_SAMP2 for (i=0; i<3; i++) n1++; n2++;
int main(void)
{
int i;
int n1 = 0;
int n2 = 0;
for (i=0; i<3; i++)
MACRO_SAMP1
printf("MACRO_SAMP1\nn1 = %d\nn2 = %d\n\n", n1, n2);
n1 = 0;
n2 = 0;
MACRO_SAMP2
printf("MACRO_SAMP2\nn1 = %d\nn2 = %d\n", n1, n2);
return 0;
}
オプション無しでコンパイルを実行
$ gcc sample.c 警告無し
$ ./a.out
MACRO_SAMP1
n1 = 3
n2 = 1
MACRO_SAMP2
n1 = 3
n2 = 1
$ マクロ置換後のコードが同じになるため実行ファイルの結果は同一となる
-Wmultistatement-macrosオプション使用してコンパイルを実行
$ gcc -Wmultistatement-macros sample.c
sample.c: In function ‘main’:
sample.c:4:21: warning: macro expands to multiple statements [-Wmultistatement-macros]
#define MACRO_SAMP1 n1++; n2++;
^~
sample.c:16:3: note: in expansion of macro ‘MACRO_SAMP1’
MACRO_SAMP1
^~~~~~~~~~~
sample.c:15:2: note: some parts of macro expansion are not guarded by this ‘for’ clause
for (i=0; i<3; i++)
^~~
$ 警告発生はfor文を含まないMACRO_SAMP1のみ
-Wallオプション使用してコンパイルを実行
$ gcc -Wall sample.c
sample.c: In function ‘main’:
sample.c:4:21: warning: macro expands to multiple statements [-Wmultistatement-macros]
#define MACRO_SAMP1 n1++; n2++;
^~
sample.c:16:3: note: in expansion of macro ‘MACRO_SAMP1’
MACRO_SAMP1
^~~~~~~~~~~
sample.c:15:2: note: some parts of macro expansion are not guarded by this ‘for’ clause
for (i=0; i<3; i++)
^~~
$ -Wallに-Wmultistatement-macrosが含まれるため同一の出力結果