extern void myprint(unsigned char *);
static inline void
myfunc(unsigned char *buf)
{
for (unsigned int i = 0; i < 20; i++) {
buf[i] = i;
}
}
int
main(void)
{
unsigned char buf[10];
myfunc(buf);
myprint(buf);
return 0;
}
$ gcc.exe -O2 -pedantic -Wextra -Wall -Wstringop-overflow -Wuninitialized -Wunused -Warray-bounds=2 -Wformat-overflow -Wstringop-overread -g -c C:\temp\cb\main.c -o build\mingw\obj\main.o
$ gcc.exe -o build\mingw\test.exe build\mingw\obj\main.o build\mingw\obj\mod.o -O2
$ gcc --version
gcc (i686-posix-sjlj-rev1, Built by MinGW-W64 project) 11.2.0
Copyright (C) 2021 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.
If the inline function is written directly inside main(), gcc complains with an array out-of-bounds warning, but why it isn't able to detect the same warning with a static inline function?
I don't know very well the output assembler, but it seems to me the loop generated really is for 20 times, so the overbound is real during execution.
Edited at 1st December 2023, 09:13
After reading some replies, I tried to change myfunc() API, but with -O2, no warning is emitted by gcc.
#include <stddef.h>
extern void myprint(unsigned char *);
static inline void
myfunc(unsigned char *buf, size_t size)
{
for (unsigned int i = 0; i < size + 1; i++) {
buf[i] = i;
}
}
int
main(void)
{
unsigned char buf[10];
myfunc(buf, 10);
myprint(buf);
return 0;
}
inlineis just a (mostly obsolete) recommendation to the compiler, it doesn't enforce inlining. As it happens, you do get the warning under-O3but not under-O2. Some things of note:-O2/-O3option does inline the function (on x86_64 gcc 13.3) but in different ways and one way with-O3happens to be one that renders the diagnostic message.inlinekeyword doesn't change the generated assembly nor the decision to inline the slightest.__attribute__((always_inline))has no affect on whether you get the warning or not either.The best practice here is not to rely on gcc giving this warning - out of bounds access bugs in C rarely ever comes with the luxury of compiler warnings. Instead you could design the function in a type safe way:
or
Or if taken to the extreme (very safe but cumbersome API):