4

考虑以下函数声明和定义。在头文件中:

void some_function(int param);

在源文件中:

#include "test.h"

void some_function(const int param) {}

int main(void) {
    return 0;
}

在 Visual Studio 2010 下,编译为纯 C 项目,我看到warning C4028: formal parameter 1 different from declaration. 但据我所知,这是完全有效的 C 语言,也是相当普遍的做法。

我对此是否错了,因此 VS2010 是否正确地警告我?或者如果它是一个虚假的警告,我可以专门针对这种情况禁用它,但在参数类型不匹配的实际情况下保持警告吗?

(VS2010自带的实际编译器是:Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86。我的命令行很简单cl test.c。)

4

1 回答 1

3

C893.5.4.3 Function declarators对参数有这样的说法:

对于要兼容的两种函数类型,两者都应指定兼容的返回类型。此外,参数类型列表(如果两者都存在)应在参数数量和省略号终止符的使用方面达成一致;相应的参数应具有兼容的类型。

部分3.1.2.6 Compatible type and composite type将兼容类型指定为具有相同类型的类型。它引用3.5.3了类型限定符(其中const之一)并指出

对于要兼容的两个限定类型,两者都应具有兼容类型的相同限定版本;说明符或限定符列表中类型限定符的顺序不影响指定的类型。

现在,您通常会因此认为它intconst int兼容的类型。但是,我认为这是对标准的误读,因为int它不是合格的类型,因此上面的引用不适用。

稍后有一个适用的引用3.5.4.3说明:

对于使用限定类型声明的每个参数,其用于这些比较的类型是其声明类型的非限定版本。

因此intconst int被类似地比较并且应该被允许。但这仅意味着根据标准它不是错误。微软可能仍然认为这是一个可疑的行为,也是发出警告的充分理由。

即使您认为这是一个问题,Microsoft 也不太可能为您解决它(见下文)。


现在您可能想知道,当有更多现代标准可用时,我为什么要引用 C89。

这是因为 Microsoft 毫不掩饰 Visual C++ 主要是 C++ 编译器,并且只能将 C 代码编译为标准的早期迭代,如下所示

感谢您抽出宝贵时间向我们发送您的建议。目前,没有计划在 VS2010 中实现 C99 支持。一旦我们完成了这个产品周期,我们将审查所有客户的建议,包括这个,以便我们未来的规划。- 马克·罗伯茨,微软。

而且,从维基百科页面

根据 Herb Sutter 的说法,C 编译器只是出于“历史原因”而包含在内,不打算进一步开发。建议用户要么仅使用也是有效 C++ 的 C 语言子集,然后使用 C++ 编译器来编译他们的代码,或者只使用不同的编译器,例如 Intel C++ Compiler 或 GNU Compiler Collection。

这在 Herb Sutter 自己的博客中得到了证实,相关文章在这里

我们不打算支持不属于 C90 或 ISO C++ 的 ISO C 功能。

于 2014-04-02T03:48:34.907 回答