1

The code:

#include <stdio.h>

void Print(char str[100])
{   
    printf("%s", str);
}

int main(void)
{
    Print("A");
}

When compiled with GCC 11.1 and above produces the warning

warning: 'Print' accessing 100 bytes in a region of size 2 [-Wstringop-overflow=]

when I pass it a smaller string. This is without any warning flags enabled.

Sample code: https://godbolt.org/z/nWs1PK9Y6

As you can see other compilers do not compain about this.

I did found a thread with a related issue but regarding an int array, which is even stranger:

GCC 11 gives -Wstringop-overflow when no string operation is used

However this is definitely a bug, was corrected, and does not occur anymore in tip-of-trunk version whereas in the code I show it still has the same warning in trunk.

I believe this to be another bug, or at least a not very useful warning as, to best of my knowledge, that argument will decay to a pointer, but I wanted to confirm that.


As stated in the comment section this can be useful to warn the API user that a smaller string is being passed as argument, but does it really make sense, at least to have it being showed with no warning flags enabled?

Passing a string to larger array is trivial in other situations. To me it would make more sense to warn the user if the passed string was larger than what the parameter is supposed to take, but if I pass a string larger than 100, the warning goes away.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • 1
    Perhaps the compiler assumes that you wouldn't write [100] if you didn't want to pass a pointer to 100 bytes? – user253751 Apr 26 '22 at 15:31
  • 2
    Although AFAIK the `100` has no actual effect on the code, typically you would use that as "documentation" for the programmer that they should pass an array with space for at least 100 elements. (If you used `static` the compiler could assume it is mandatory). GCC picks up on that hint and notices that you don't seem to be following your own rule, hence the warning about a potential bug. It seems reasonable to me. If you are not using the array size in this way, then you can simply disable the warning `-Wno-stringop-overflow`. – Nate Eldredge Apr 26 '22 at 15:36
  • @user253751 perhaps, I wouldn't use such construct as to me it's pointless, at least I thought it was. – anastaciu Apr 26 '22 at 15:37
  • @NateEldredge I agree for the most part, but I would thing this would be a low level warning, one that would make sense to include when `-pedantic` flag is used, or at least `-Wall`. – anastaciu Apr 26 '22 at 15:40
  • And, to me, it makes more sense a warning when there is potential for overflow, to pass a smaller string to an array that can take a larger string is trivial, and is not a problem for most cases, unless you are dealing with a very limited amount of storage, which is not normally the case. – anastaciu Apr 26 '22 at 15:46
  • I interpret `void func(char buf[100])` not as indicating that `func` *can* take an array of length up to 100, but that it *must* take an array of length at least 100. Such as a function which will unconditionally read or write 100 elements. With that interpretation your code would certainly merit a warning because it would be risking an overrun (though GCC doesn't notice that `Print` doesn't in fact read or write that many characters). Personally, if the compiler thinks I may be overrunning a buffer, I'd want that to be a warning of the highest possible priority. – Nate Eldredge Apr 26 '22 at 15:52
  • @Nate you're right, I removed the tag – anastaciu Apr 26 '22 at 15:55
  • 1
    Note that if you used `void Print(char str[static 100])`, the warning (or a similar one) would be fully justified; the `static` says you promise to pass a pointer to at least 100 bytes of data. It's not clear the warning is justified with the code as written. – Jonathan Leffler Apr 26 '22 at 17:01

1 Answers1

5

The -Wstringop-overflow=4 option uses type-three Object Size Checking to determine the sizes of destination objects. At this setting the option warns about overflowing any data members, and when the destination is one of several objects it uses the size of the largest of them to decide whether to issue a warning. Similarly to -Wstringop-overflow=3 this setting of the option may result in warnings for benign code.

source: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

If char str[100] was char str[], then gcc would automatically changes it to char *.

This warning can be suppressed by using optimization flag -O2 or -O3.

Darth-CodeX
  • 2,166
  • 1
  • 6
  • 23