如何规避GCC中的格式截断警告?

问题描述 投票:8回答:3

我收到以下gcc格式 - 截断警告:

test.c:8:33: warning: ‘/input’ directive output may be truncated writing 6 bytes into a region of size between 1 and 20 [-Wformat-truncation=]
snprintf(dst, sizeof(dst), "%s-more", src);
                             ^~~~~~
test.c:8:3: note: ‘snprintf’ output between 7 and 26 bytes into a destination of size 20
snprintf(dst, sizeof(dst), "%s-more", src);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

像这样的代码:

char dst[20];
char src[20];
scanf("%s", src);
snprintf(dst, sizeof(dst), "%s-more", src);
printf("%s\n", dst);

我知道它可能会被截断 - 但这正是我首先使用snprintf的原因。有没有办法让编译器明白这是预期的(不使用编译指示或-Wno格式截断)?

c gcc format gcc-warning
3个回答
10
投票

  1. 警告已经在gcc7.1中被侵入,请参阅gcc7.1 release changes
  2. 来自gcc docs

-Wformat-truncation [...]的级别1仅警告对有效函数的调用,这些函数的返回值未使用,并且很可能导致输出截断。

  1. 问题是bug report,并作为NOTABUG关闭:

未处理的输出截断通常是程序中的错误。 [...] 在期望截断的情况下,调用者通常检查函数的返回值并以某种方式处理它(例如,通过在其上分支)。在这些情况下,不会发出警告。警告打印的源代码行表明这不是其中之一。警告正在做它的设计目的。

  1. 但是我们可以检查snprintf的返回值,它会在出错时返回负值。

#include <stdio.h>
#include <stdlib.h>
void f(void) {
    char dst[2], src[2];
    // snprintf(dst, sizeof(dst), "%s!", src);

    int ret = snprintf(dst, sizeof(dst), "%s!", src);
    if (ret < 0) {
         abort();
    }

    // But don't we love confusing one liners?
    for (int ret = snprintf(dst, sizeof(dst), "%s!", src); ret < 0;) exit(ret);
    // Can we do better?
    snprintf(dst, sizeof(dst), "%s!", src) < 0 ? abort() : (void)0;
    // Don't we love obfuscation?
#define snprintf_nowarn(...) (snprintf(__VA_ARGS__) < 0 ? abort() : (void)0)
    snprintf_nowarn(dst, sizeof(dst), "%s!", src);
}

用含有https://godbolt.org/的gcc7.1 gcc7.2 gcc7.3 gcc8.1在-O{0,1,2,3} -Wall -Wextra -pedantic上进行测试。没有任何警告。 gcc8.1优化/删除对abort()的调用,优化大于-O1


3
投票

您可以添加精度说明符。这将从src打印最多14个字符,避免可能截断格式字符串,并且不会触发该警告:

snprintf(dst, sizeof(dst), "%.14s-more", src);

online compiler


-1
投票

归入由于格式截断警告而无法编译的项目,但使用的唯一标志是format=2

我发了一封信给开发商提供建议。显然,他们出于某种原因指定了-Wformat选项,并且在禁用它时允许项目构建,这不是有意的,当然也不推荐。

-Wformat = 2

Enable -Wformat plus additional format checks. Currently equivalent to -Wformat -Wformat-nonliteral -Wformat-security -Wformat-y2k.

-Wformat截断= 2

Level 2 warns also about calls to bounded functions whose return value is used and that might result in truncation given an argument of sufficient length or magnitude. 

GNU Compiler Warnings

© www.soinside.com 2019 - 2024. All rights reserved.