【问题标题】:Is Visual Studio's C4028 warning (formal parameter different from declaration) spurious?Visual Studio 的 C4028 警告(与声明不同的形式参数)是虚假的吗?
【发布时间】:2013-08-30 03:15:26
【问题描述】:

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

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。)

【问题讨论】:

  • 有趣。您在“常见做法”中在哪里看到过这种情况?是的,警告你是正确的,但在这种情况下,无论如何它都无关紧要,因为它是一个值参数,并且在实现方面的启动限制更大。用 pointer 来做这件事,它会产生 big 的不同。例如:考虑const char*原型char * 在实现中的影响。
  • @WhozCraig - 带有指针参数的等价物是char *const param,而不是const char *param
  • @WhozCraig - 但是,我知道这没关系,这就是我的观点。这告诉编译器和任何开发人员 param 不能被函数体更改,这是一个不需要在声明中公开的实现细节。那么为什么VS2010在没有不兼容、没有行为差异、没有意外行为可能性的情况下会发出警告呢?
  • 我明白了。我使用间接修改功能的差异来简单地说明它可以有所作为,但我当然明白你的观点,如果参数 var itself 是 @ 987654330@,那又何必呢。为此,我所能提供的就是:除了您在此处引用的特定 const-param 条件之外,该潜在警告在任何地方都有意义吗?如果是这样,是否可以想象,为此压制它,您可能会为其他人错过它?无论如何,我同意你在这种特定情况下的不必要性。 (对一个有趣的问题 +1)。
  • @WhozCraig - 您还会收到警告,例如。声明一个采用int 的函数,但将其定义为采用long,反之亦然,这是我 想知道的(可能还有float/int肯定想要一个警告,但我还没有检查)。

标签: c visual-studio-2010 c89


【解决方案1】:

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

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

3.1.2.6 Compatible type and composite type 部分将兼容类型指定为具有相同类型的类型。它引用 3.5.3 的类型限定符(其中 const 是一个)并且 that 声明:

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

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

3.5.4.3 后面有一个更适用的引述 声明:

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

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

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


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

这是因为 Microsoft 毫不掩饰 Visual C++ 主要是一个 C++ 编译器,并且只能将 C 代码编译为标准的早期版本,如 here

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

还有,来自wikipedia page

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    相关资源
    最近更新 更多