【问题标题】:what does a c compiler do when doesn't find the matching function当找不到匹配的函数时,c 编译器会做什么
【发布时间】:2011-11-27 13:02:18
【问题描述】:

考虑以下代码:

#include<stdio.h>
int f()
{
        printf(" hey ");
        return 5;
}
int main()
{
        printf("hello there %d",f(4,5));
        f(4,5);
        return 0;
}

我预计函数“int f()”的参数太多,但即使在严格的 C99 编译中它也会给出输出。为什么this 的行为? 但似乎 C++ 编译器会出错。

【问题讨论】:

  • 如果f 的定义与调用它的函数在同一个文件中,那么好的编译器会发出警告。但是,如果只看到声明,代码就是合法的。
  • 一个不错的编译器??标准的 gcc 没有抛出任何错误?
  • @Lindydancer:代码是合法的。 int f() 声明 f 接受你喜欢的任何参数。
  • @JeremyP: 6.5.2.2.6: “如果表示被调用函数的表达式的类型不包含原型 [...]。如果参数的数量不等于参数数量,行为未定义。”在这种情况下,编译器在编译main时看到f定义,可以断定存在不匹配并发出警告。

标签: c function c99


【解决方案1】:

在某些方面,C 比 C++ 严格得多。

C++ 中的函数签名f() 表示没有参数的函数,并且符合标准的编译器必须强制执行此操作。相比之下,在 C 中,行为是未指定的,编译器不需要诊断是否使用参数调用函数,即使它是在没有参数的情况下定义的。在实践中,现代编译器至少应该警告无效用法。

此外,在 C 中的函数原型声明(无定义)中,空括号表示参数未指定。随后可以使用任意数量的参数对其进行定义。

为防止这种情况发生,请使用以下原型ISO/IEC 9899 6.7.6.3/10

int f(void)

【讨论】:

  • 对。更准确地说,编译器不需要诊断使用错误数量和/或类型的参数调用它。行为未定义。
【解决方案2】:

除了 Konrad 所写的,C 还会为您隐式声明函数。例如:

int main(int argc, char** argv)
{
  int* p = malloc(sizeof(int));
  return 0;
}

将在没有包含声明的#include &lt;stdlib.h&gt; 的情况下编译(可能带有警告)。

【讨论】:

  • 隐式函数定义在 C99 中是非法的。你的编译器应该至少给你一个警告。
  • @JeremyP gcc -std=c99 -c program.c 只给了我一个警告?你确定它是非法的吗?
  • @sashan:标准要求诊断格式错误的代码,而不是编译失败。警告是一种诊断。允许实现以实现喜欢的任何行为对其进行编译。
  • C99 不需要对问题中的代码发出警告。 f定义 提供了一个旧式声明:int f(),它告诉编译器 f 是一个返回 int 的函数,但不知道它需要多少个参数。 C99 要求被调用函数的可见声明;它不(不幸的是恕我直言)要求这些声明是原型。 (即使是 C201X 草案也没有删除旧式函数声明和定义。)
  • 至于这个答案中的代码,它在 C90 和 C99 中都是违反约束的,但原因不同。在 C90 中,对 malloc 的调用会创建一个隐式声明:int malloc(size_t);。没有从intint* 的隐式转换。在 C99 中,调用需要诊断,因为没有可见的声明。
猜你喜欢
  • 1970-01-01
  • 2011-04-20
  • 1970-01-01
  • 1970-01-01
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多