On 2 March 2018 at 14:27, Mason wrote: > Hello, > > Consider the following testcase: > > #include <stdio.h> > > struct foo { int val; char txt[60]; }; > > void bar(struct foo *p) > { > char buf[80]; > snprintf(buf, sizeof buf, "%s%s", p->txt, p->txt); > } > > > Compiled at different optimization levels: > > > $ gcc-7 -O0 -Wall -S bug.c > bug.c: In function 'bar': > bug.c:8:31: warning: '%s' directive output may be truncated writing up to 59 bytes into a region of size between 21 and 80 [-Wformat-truncation=] > snprintf(buf, sizeof buf, "%s%s", p->txt, p->txt); > ^~ > bug.c:8:2: note: 'snprintf' output between 1 and 119 bytes into a destination of size 80 > snprintf(buf, sizeof buf, "%s%s", p->txt, p->txt); > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > $ gcc-7 -O1 -Wall -S bug.c > bug.c: In function 'bar': > bug.c:8:31: warning: '%s' directive output may be truncated writing up to 59 bytes into a region of size between 21 and 80 [-Wformat-truncation=] > snprintf(buf, sizeof buf, "%s%s", p->txt, p->txt); > ^~ > In file included from /usr/include/stdio.h:936:0, > from bug.c:1: > /usr/include/x86_64-linux-gnu/bits/stdio2.h:64:10: note: '__builtin___snprintf_chk' output between 1 and 119 bytes into a destination of size 80 > return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > __bos (__s), __fmt, __va_arg_pack ()); > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > Note: Using godbolt CE, GCC trunk prints the first warning for all optimization levels. > > > I am confused by both of these warnings. > I am aware that adding two 60-char strings might overflow an 80-char buffer, > which is why I'm using snprintf. In which case the output would be truncated instead of overflowing, and that's what the warning says. > I'm not sure these warnings are very helpful. What am I missing? > (I may have oversimplified the testcase.) I think the point is that although you avoid undefined behaviour, you might still not get the output you expected.