I understand that newer GCC versions introduced a warning for possibly wrong string operations "stringop-truncation"
And here's the sample code that I can easily trigger this warning:
$ cat strncpy-warning.cxx
#include <cstring>
extern char g_buf[16];
void mycopy ( const char* src_c_str )
{
strncpy ( g_buf, src_c_str, sizeof ( g_buf ) );
}
Compile it with the following flags triggers this warning:
$ g++ --version
g++ (GCC) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -Wall -std=c++14 -Wextra -Werror -O3 -c strncpy-warning.cxx
strncpy-warning.cxx: In function ‘void mycopy(const char*)’:
strncpy-warning.cxx:7:13: error: ‘char* strncpy(char*, const char*, size_t)’ specified bound 16 equals destination size [-Werror=stringop-truncation]
strncpy ( g_buf, src_c_str, sizeof ( g_buf ) );
~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
Which is expected, however, if I added an -flto
to the flags, this warning is gone and the object file is generated:
$ g++ -Wall -std=c++14 -Wextra -Werror -O3 -c strncpy-warning.cxx -flto
$ ls strncpy-warning.o
strncpy-warning.o
Apparently, -flto
WILL catch some compile time warnings so not sure why that stringop-truncation
is not caught, e.g.:
$ cat strncpy-warning.cxx
#include <cstring>
extern char g_buf[16];
void mycopy ( const char* src_c_str, const char* unused )
{
strncpy ( g_buf, src_c_str, sizeof ( g_buf ) );
}
$ g++ -Wall -std=c++14 -Wextra -Werror -O3 -c strncpy-warning.cxx -flto
strncpy-warning.cxx: In function ‘void mycopy(const char*, const char*)’:
strncpy-warning.cxx:5:50: error: unused parameter ‘unused’ [-Werror=unused-parameter]
void mycopy ( const char* src_c_str, const char* unused )
~~~~~~~~~~~~^~~~~~
cc1plus: all warnings being treated as errors
So the question is:
-flto
specified for a source file, GCC will write special things into the resulting object file ( *.o
), but the question is why the warning is skipped by GCC? Is that intentional?-flto
is given?Many thanks!
Roughly speaking, GCC has two kinds of warnings:
An unused parameter is the first kind: it's trivial to see that a parameter is simply not used in a function.
Incorrect usage of strncpy
is, except for trivial cases, the second kind: the compiler needs to understand the relationship between the first and third arguments to strncpy
, it needs to know the actual (or at least symbolic) value passed in the third argument, and it needs to know the actual (or at least symbolic) size available in the first argument.
The first kind of warning is generated by the frontend parser. Thus, it always fires.
The second kind is generated by the same component that optimizes the code, because only this component has the necessary information. In -flto
mode, this component doesn't run for individual source files.
The second kind also sometimes depends on specific optimizations being performed at all: if you change the optimization level in your first command line to -O1
, the warning isn't emitted either.