c - 为什么 C 标准允许这段代码编译无误?

标签 c language-lawyer

<分区>

这里有一段代码似乎没有错误地被接受:

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

int main() {
    if (strcmp(1, 2))
        printf(3);
}

使用 clang -std=c11 -Weverything 编译会产生 4 条警告:

badstrcmp.c:5:16: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *' [-Wint-conversion]
    if (strcmp(1, 2))
               ^
/usr/include/string.h:77:25: note: passing argument to parameter '__s1' here
int      strcmp(const char *__s1, const char *__s2);
                            ^
badstrcmp.c:5:19: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *' [-Wint-conversion]
    if (strcmp(1, 2))
                  ^
/usr/include/string.h:77:43: note: passing argument to parameter '__s2' here
int      strcmp(const char *__s1, const char *__s2);
                                              ^
badstrcmp.c:6:16: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'const char *' [-Wint-conversion]
        printf(3);
               ^
/usr/include/stdio.h:259:36: note: passing argument to parameter here
int      printf(const char * __restrict, ...) __printflike(1, 2);
                                       ^
badstrcmp.c:6:16: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
        printf(3);
               ^
badstrcmp.c:6:16: note: treat the string as an argument to avoid this
        printf(3);
               ^
               "%s",
4 warnings generated.

我的问题是为什么 C 标准允许它编译?。这种问题应该被诊断为错误,代码应该被拒绝。为什么 C 标准允许程序被翻译?

最佳答案

您的问题似乎基于一个无效前提,即 C 标准以某种方式“允许此代码编译”。实际上C标准并没有“允许或不允许代码编译”这样的概念。

如果代码无效,标准要求编译器通过诊断消息告知您。该标准不要求编译器拒绝编译您的代码。他们仍然可以继续以某种实现定义的方式对其进行编译。

根据 C 标准,您的代码明显无效。标准 C 语言不允许隐式整数到指针的转换。你的编译器通过诊断消息清楚地告诉你。这足以让编译器满足标准的要求。

在那之后,所有赌注都取消了。你的编译器可能会把它编译成“东西”,但这不是一个符合标准的 C 程序。它的行为不是由语言定义的。

至于您收到的诊断消息的格式(以及它们是“警告”还是“错误”)——这是您的编译器的问题。在 C 中,这是一个实现质量问题。 C 标准与它无关。

您可以要求 clang 通过提供 -pedantic-errors 标志将 C 语言约束违规报告为“错误”。对于这个目的来说它并不完美,但它会让编译器拒绝编译你的代码(如果那是你想要的)。

关于c - 为什么 C 标准允许这段代码编译无误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42179504/

相关文章:

c - 定义的魔数(Magic Number)后跟 CRC 有什么用

c - 遗留代码 : mmap zero page: Operation not permitted - where should i start?

c++ - 作为非类型模板参数的引用

c++ - 条件运算符 + upcast + const 引用

c++ - 为什么在 C++ 中允许多个预增量但在 C 中不允许?

c++ - 为什么 `int ;` 在 C 中编译得很好,但在 C++ 中却不行?

c - 如果字符的最大容量是256,如何存储1000个字符数组?

c++ - 在当前 C++ 草案的 [namespace.def]/2 中,下面突出显示的表达式 `that namespace` 指的是哪个命名空间?

c++ - std::array 的大小是否由标准定义

c - 结构数组成员的指针转换问题