GCC diagnoses the out-of-bounds reads by strcmp in fx and f0 but fails to diagnose the corresponding out-of-bounds reads by strncmp in gx and g0. In all four functions the size of the character array is zero and so each call to the string function starts reading past its end, and so past the end of the enclosing object. $ cat b.c && gcc -O2 -S -Wall -Wextra b.c extern int strcmp (const char*, const char*); void init (void*); int fx (void) { struct { char n, a[]; } a; init (&a); return 0 == strcmp (a.a, "123"); // -Wstringop-overread (good) } int f0 (void) { struct { char n, a[0]; } a; init (&a); return 0 == strcmp (a.a, "123"); // -Wstringop-overread (good) } extern int strncmp (const char*, const char*, __SIZE_TYPE__); int gx (void) { struct { char n, a[]; } a; init (&a); return 0 == strncmp (a.a, "123", 3); // missing -Wstringop-overread } int g0 (void) { struct { char n, a[0]; } a; init (&a); return 0 == strncmp (a.a, "123", 3); // missing -Wstringop-overread } b.c: In function ‘fx’: b.c:9:15: warning: ‘strcmp’ reading 1 or more bytes from a region of size 0 [-Wstringop-overread] 9 | return 0 == strcmp (a.a, "123"); // -Wstringop-overread (good) | ^~~~~~~~~~~~~~~~~~~ b.c:7:20: note: source object ‘a’ of size 0 7 | struct { char n, a[]; } a; | ^ b.c: In function ‘f0’: b.c:16:15: warning: ‘strcmp’ reading 1 or more bytes from a region of size 0 [-Wstringop-overread] 16 | return 0 == strcmp (a.a, "123"); // -Wstringop-overread (good) | ^~~~~~~~~~~~~~~~~~~ b.c:14:20: note: source object ‘a’ of size 0 14 | struct { char n, a[0]; } a; | ^