【问题标题】:Same program gives compiler error in one compiler and not the other同一程序在一个编译器而不是另一个编译器中给出编译器错误
【发布时间】:2019-09-18 07:23:23
【问题描述】:

我正在学习 Simon Long 的 Learn to Code with C。 https://www.raspberrypi.org/magpi-issues/Essentials_C_v1.pdf 在第 20 页有这个简单的程序:

#include <stdio.h>
void main (void)
 {
  int a = 0;
  while (a < 5)
{
  printf ("a is equal to %d\n", a);
  a++;
}
  printf ("a is equal to %d and I've finished\n", a);
}

但是当我编译这个时,我得到了这个编译器错误:

while-loop.c:3:1: warning: return type of 'main' is not 'int'
  [-Wmain-return-type]
void main(void)
^
while-loop.c:3:1: note: change return type to 'int'
void main(void)
^~~~
int
1 warning generated.

这是为什么?似乎作者的编译器没有为此给出错误。为什么会出现差异?

当我改变时

void main (void) 

到

int main (void)

它编译得很好。

【问题讨论】:

  • void main 是编译器可能实现也可能不实现的扩展。标准的main 返回类型是int。
  • 我不相信从一本包含 main() 的错误签名之类的书中学习。
  • 或许作者 Simon Long 是从著名的 C 专家 Herbert Schildt 那里学来的? ;-)
  • @Shawn 我不会相信每页有这么多彩色装饰的书。

标签: c


【解决方案1】:

每5.1.2.2.1 Program startup, paragraph 1 of the C standard(我的粗体字):

程序启动时调用的函数名为main。这 实现没有声明这个函数的原型。 应该是 使用 int 的返回类型定义并且没有参数:

     int main(void) { /* ... */ }

或带有两个参数(此处称为 argc 和 argv,尽管任何 可以使用名称,因为它们对于它们所在的函数是本地的 声明):

     int main(int argc, char *argv[]) { /* ... */ }

或等价物;或以其他一些实现定义的方式。

虽然void main() 确实适合“或其他一些实现定义的方式”,但在我看来,一个特定的实现特定的扩展不属于初学者的文本,至少需要一些解释,因为它只会导致后面的混乱。

至少找一本不会让眼睛那么痛的书。

【讨论】:

  • int main(void) - 不带参数。 int main() - 采用未指定数量的参数。函数定义只能使用前者。
  • @snr 看看这个问题:stackoverflow.com/questions/22073893/…
  • @snr:除非编译器文档明确将其列为有效签名,否则void main() 会导致未定义行为,这意味着它被视为错误代码,但编译器不是需要以任何特定方式处理它。有一些(当然是旧的和/或古怪的平台)使用void main() 可能会导致代码在启动时崩溃。较新的编译器倾向于对此发出警告,但严格来说,它们不是必需。这就是很多未定义行为的问题,您可能不会收到有关它的警告。
  • @snr - 在函数 definition(您指定函数体的位置)中,空参数列表与 void 的参数列表含义相同 - 函数不接受任何论据。所以int main(void) { ... } 和int main( ) { ... } 都是同一个意思。在函数 declaration 中(您只指定函数名称和参数列表),空参数列表意味着函数接受 未指定 数量的参数,因此 int foo(); 和int foo(void); 表示不同的东西。作为风格问题,始终使用 void 而不是空参数列表来表示没有参数。
  • @EugeneSh.: 作为函数定义的一部分,是的。 6.7.6.3/14:“标识符列表仅声明函数参数的标识符。作为该函数定义一部分的函数声明器中的空列表指定该函数没有参数。 函数声明符中不属于该函数定义的空列表指定不提供有关参数数量或类型的信息。”
猜你喜欢
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
  • 2013-04-23
  • 1970-01-01
相关资源
最近更新 更多