4

gcc 7.1 has introduced a new warning that tells you if you use functions such as snprintf and your arguments would result in output truncation.

The documentation implies that it is only raised if you don't check and act upon the return value:

Level 1 of -Wformat-truncation enabled by -Wformat employs a conservative approach that warns only about calls to bounded functions whose return value is unused and that will most likely result in output truncation.

Here's a sample compilation unit, compiled with version 7.3.0 that illustrates the issue.

#include <stdio.h>
#include <stdlib.h>

int main() {

  char w;

  int size = snprintf(&w, 1, "%s", "hello world");
  if(size<0) {
    abort();
  }

  char *buffer = malloc(size+1);
  snprintf(buffer, size+1, "%s", "hello world");

  printf("Wrote %d characters: %s\n", size, buffer);
  return 0;
}

Compiled like this:

$ gcc -Wformat-truncation=1 test.c
test.c: In function ‘main’:
test.c:8:31: warning: ‘%s’ directive output truncated writing 11 bytes into a region of size 1 [-Wformat-truncation=]
   int size = snprintf(&w, 1, "%s", "hello world");
                               ^~   ~~~~~~~~~~~~~
test.c:8:7: note: ‘snprintf’ output 12 bytes into a destination of size 1
   int size = snprintf(&w, 1, "%s", "hello world");

Am I misinterpreting the documentation? I can't see how I could check the return value more than I am doing already.

Reference: previous SO question that implies the warning should not be raised. I really don't like disabling warnings and usually compile with -Wall -Werror so I'd appreciate some guidance here.

Andy Brown
  • 11,766
  • 2
  • 42
  • 61
  • Why a downvote? – gsamaras Nov 16 '18 at 09:45
  • 1
    No idea why gcc acts like this. But shadowing the numerical size with a variable shuts it up. [godbolt](https://gcc.godbolt.org/z/syPMM0). – merlyn Nov 16 '18 at 10:13
  • @merlyn unfortunately `-O` then brings the warning back. – Andy Brown Nov 16 '18 at 11:04
  • The first `snprintf` call will be unable to do more than write a null byte into `w`; that is warning-worthy. What happens if you have `char w[2];` and modify the call appropriately? – Jonathan Leffler Nov 16 '18 at 12:21
  • @JonathanLeffler The warning persists with `char w[2]` except of course it's now `...into a destination of size 2` – Andy Brown Nov 16 '18 at 14:25
  • I see this behaviour on msys gcc 7.4, but not mingw gcc 8.3. I even tried adding in ` size >= 1` to see if that would satisfy it. – Pod May 10 '19 at 15:03

0 Answers0