https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89312

--- Comment #5 from Martin Sebor <msebor at gcc dot gnu.org> ---
In the future, the warnings for problems unrelated to truncation should be
moved under their own options (e.g., null pointer arguments to %s should be
controlled by either -Wnonnull or -Wnull-dereference).

Your solution/workaround will work but GCC will only eliminate the test when it
can prove the condition cannot be true.  For example, below the test and the
assignment are eliminated because given the sizes of the two input arrays the
snprintf result cannot be greater than 40 (compile with
-fdump-tree-optimized=/dev/stdout to see the result):

  char a[20], b[20];
  char d[40];

  void f (void)
  {
    int r = snprintf (d, sizeof d, "%s %s", a, b);
    if (r >= sizeof d)
      d[sizeof d - 1] = 0;
  }

But if you change a to have, say, 30 elements (or make it a pointer) the test
is not eliminated anymore because GCC can no longer prove that it won't cause
truncation (the possible truncation can then be detected by using
-Wformat-truncation=2).

The same effect can be achieved without the overhead by introducing a volatile
temporary variable for the destination size, but it's also ugly.  Another
option is to introduce a wrapper function or macro for deliberately truncating
snprintf calls and have it hide the ugliness:

  #define snprintf_trunc(dst, size, ...) \
    do {                                 \
      volatile size_t n = size;          \
      snprintf (dst, n, __VA_ARGS__);    \
    } while (0)

I agree that clunky workarounds shouldn't be necessary.  Ideally, there would
be an elegant or at least intuitive way to indicate the truncation is expected
without jumping through these hoops.  A few people have suggested a cast to
void as that annotation.  We had considered it but didn't implement it because
legacy code routinely uses casts to void as a (superfluous) convention to
indicate that the result of a function call is deliberately unused, but not
necessarily with an appreciation of the consequences of what it might mean for
snprintf.  Perhaps we should revisit that decision.

Reply via email to