3

With avr-gcc 14, the compiler gives this warning:

avrenv.c: In function ‘main’
avrenv.c:12:13: warning: ‘strncpy’ output may be truncated copying 255 bytes from a string of length 509 [-Wstringop-truncation]
12 |             strncpy(dest, src[i], 255);
   |             ^~~~~~~~~~~~~~~~~~~~~~~~~~

for this (minimal reproducer):

#include <stdint.h>
#include <stdio.h>
#include <string.h>

int main(void) {

    while (1) {
        char src[2][255] = {{'a', '\0'}, {'b', '\0'}};

        for (uint8_t i = 0; i < 2; i++) {
            char dest[255];
            strncpy(dest, src[i], 255);
            puts(dest);
        }
    }

    return 0;
}

The warning is however only given with -O2, with for example -O1 or no optimization, there is no warning. It seems that x86-64 gcc does the same.

I am just curious - why is the warning given with -O2, and why length 509?

1 Answer 1

2

For warnings about the behavior of a code, rather than strictly its syntax, it's normal for optimization level to have an effect, as this determines the level of analysis that the compiler performs. For instance, at lower optimization levels, the compiler may not keep track of the sizes of objects when compiling reads or writes involving pointers into them.

This is documented in general:

The effectiveness of some warnings depends on optimizations also being enabled. For example, -Wsuggest-final-types is more effective with link-time optimization. Some other warnings may not be issued at all unless optimization is enabled. While optimization in general improves the efficacy of warnings about control and data-flow problems, in some cases it may also cause false positives.

509 presumably represents the total size of the src object, minus one (255 * 2 - 1 = 509), as if it were one big string with a null terminator. GCC probably chooses to be conservative and warn about the "worst case".

GCC's stringop warnings documentation is linked to Object Size Checking, whose __builtin_object_size docs discuss how it handles the case where a pointer could point to any of several different objects (e.g. just src[0], which is of size 2, or all of src, which is of size 510). It has options to return either the largest or smallest of the possibilities. This warning probably uses "largest", again to err to the side of caution.

Sign up to request clarification or add additional context in comments.

1 Comment

Very nice answer! Now it makes good sense to me. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.