Loose-Info.com
Last Update 2021/10/28
TOP - 各種テスト - gcc - 警告関連のオプション - -Wsizeof-pointer-memaccess

-Wsizeof-pointer-memaccess
特定の文字列およびメモリ操作の関数の引数がsizeof式を使用して、バイト長の指定などで誤りが疑われる場合に警告を出力

テスト概要

オプション無し、-Wsizeof-pointer-memaccess、-Wallの各オプションを使用した際の警告出力例

実行環境

GCC-8.2.0
GNU C Library 2.28
GNU Binutils 2.31.1


コード例・出力内容中の表記

・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。

使用ファイル


sample.c
#include <stdio.h> #include <string.h> int main(void) { char s1[20] = "12345"; char s2[20]; char *p = s2; memset(s2, '\0', sizeof(s2)); /* sizeofの対象がポインタ */ printf("sizeof(p) = %ld --- ", sizeof(p)); memset(p, 'a', sizeof(p)); printf("[%s] [%s]\n", s1, s2); /* sizeofの対象が配列 */ printf("sizeof(s2) - 1 = %ld --- ", sizeof(s2) - 1); memset(p, 'b', sizeof(s2) - 1); printf("[%s] [%s]\n", s1, s2); /* sizeofの対象が配列先頭のアドレス */ printf("sizeof(&s2[0]) = %ld --- ", sizeof(&s2[0])); memcpy(&s2[0], s1, sizeof(&s2[0])); printf("[%s] [%s]\n", s1, s2); /* sizeofの対象が配列 */ printf("sizeof(s2) - 1 = %ld --- ", sizeof(s2) - 1); memcpy(&s2[0], s1, sizeof(s2) - 1); printf("[%s] [%s]\n", s1, s2); return 0; }

動作テスト

オプション無しでコンパイルを実行
$ gcc sample.c 警告無し $ ./a.out sizeof(p) = 8 --- [12345] [aaaaaaaa] sizeof(s2) - 1 = 19 --- [12345] [bbbbbbbbbbbbbbbbbbb] sizeof(&s2[0]) = 8 --- [12345] [12345] sizeof(s2) - 1 = 19 --- [12345] [12345] $

-Wsizeof-pointer-memaccessオプションを指定してコンパイルを実行
$ gcc -Wsizeof-pointer-memaccess sample.c sample.c: In function ‘main’: sample.c:14:23: warning: argument to ‘sizeof’ in ‘memset’ call is the same expression as the destination; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess] memset(p, 'a', sizeof(p)); ^ sample.c:24:27: warning: argument to ‘sizeof’ in ‘memcpy’ call is the same expression as the destination; did you mean to remove the addressof? [-Wsizeof-pointer-memaccess] memcpy(&s2[0], s1, sizeof(&s2[0])); ^ $ 各々の関数についての修正の可能性についてのコメントを出力

-Wallオプションを指定してコンパイルを実行
$ gcc -Wall sample.c sample.c: In function ‘main’: sample.c:14:23: warning: argument to ‘sizeof’ in ‘memset’ call is the same expression as the destination; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess] memset(p, 'a', sizeof(p)); ^ sample.c:24:27: warning: argument to ‘sizeof’ in ‘memcpy’ call is the same expression as the destination; did you mean to remove the addressof? [-Wsizeof-pointer-memaccess] memcpy(&s2[0], s1, sizeof(&s2[0])); ^ $ -Wsizeof-pointer-memaccessオプションは-Wallでも有効となる