为什么 gcc 不发出格式警告?

Why doesn't gcc emit a format warning?

#include <stdio.h>

void a(signed char a) {
    printf("%u\n", a);
}

void b(short b) {
    printf("%u\n", b);
}

void c(int c) {
    printf("%u\n", c);
}

void d(long d) {
    printf("%u\n", d);
}

void e(long long e) {
    printf("%u\n", e);
}

int main() {
    a(-1); //no warning
    b(-1); //no warning
    c(-1); //no warning
    d(-1); //warning
    e(-1); //warning
    return 0;
}

使用 gcc -std=c17 -pedantic -Wall -Wextra test.cg++ -std=c++17 -pedantic -Wall -Wextra test.cpp 使用 gcc 11.2.0 编译和测试。两者都不对 a()b()c() 发出任何警告。这是故意的还是错误?

简答:C 警告是个谜。如果您想在此处显示警告,请使用 -Wformat-signedness

请注意 -Wformat-signedness 需要 -Wformat,它已被 -Wall 启用。


显然,编译器仅在使用 -Wformat-signedness 时检查符号不匹配。 -Wall-Wextra 不包括 -Wformat-signedness。我不知道这是为什么。有人说这是因为它会导致太多警告,但这告诉我如果它是一个常见的错误,它确实需要使用!

因此,所有正在检查的都是尺寸不匹配。发出警告的两个(de)发出警告是因为传递的类型值可能大于 int。至于其他两个,signed charshort int 值在传递给可变参数 (...) 函数时会提升为 int 值,例如 printf,因此 ab 等同于 c.