【问题标题】:Function defined without a prototype sometimes results in conflicting types error没有原型定义的函数有时会导致类型冲突错误
【发布时间】:2023-01-25 23:26:14
【问题描述】:

我在 clang 中遇到了一个奇怪的行为(来自 Homebrew 的 AppleClang 1400.0.29.202 和 clang 15.0.7)。假设我有以下代码:

int bar();

int bar(int a, TEST b) {
    return 43;
}

它使用-DTEST=int 进行编译,但无法使用-DTEST=char进行编译,导致conflicting types for 'bar'。无论指定的标准如何(我已经尝试过c89c99)都会发生这种情况。

我错过了什么吗?

编辑:我意识到省略原型是非常不鼓励的,我不写这样的代码,但在野外仍然有很多这样写的代码。今天早上我试图编译enscript,遇到了这个问题。

此外,以下适用于-DTEST=char

int bar();

int bar(a, b)
    int a;
    TEST b;
{
    return 43;
}

【问题讨论】:

  • 我猜这是因为它与默认参数促销冲突。
  • 我错过了什么吗?是的——一个合适的函数原型。不要写那样的代码。
  • (顺便说一句,这个古老的、很久以前就过时的废话终于在 C23 中从 C 语言中删除了。)
  • 如果一种类型有一个参数类型列表,而另一种类型是由函数声明符指定的,该函数声明符不是函数定义的一部分,并且包含一个空的标识符列表,则参数列表不应有省略号终止符,并且每个参数的类型应与应用默认参数提升产生的类型兼容。”(注意:“参数类型列表”表示函数声明为函数原型形式。)char被大多数实现的默认参数提升提升为与char不兼容的类型。
  • 您可以通过使用 K&R1 样式函数定义(至少在 C23 之前)使其工作。 int bar(a, b) int a; TEST b; { return 43; }。顺便说一句,返回值中有一个差一错误。 :)

标签: c clang


【解决方案1】:

我错过了什么吗?

是的,一个正确的函数声明。代码应该是:

int bar(int a, TEST b);

int bar(int a, TEST b) {
    return 43;
}

[为什么我会收到此错误?]

int bar() 是一个函数未指定参数的计数和类型以及所有参数都经过default argument promotions,其中char被提升为int。因为 int bar() 不可能采用 char 参数,因为它会被提升为 int,这是一种冲突类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多