【问题标题】:How to make gcc happy about embedded systems and void main(void)如何让 gcc 对嵌入式系统和 void main(void) 感到满意
【发布时间】:2013-12-12 09:57:05
【问题描述】:

C115.1.2.2.1 说

it [main()] 应定义为返回类型 int

但是,第 6.7.4 节介绍了 _Noreturn 关键字,这对于准系统嵌入式系统的main() 似乎非常有用。

声明不可返回的 main() 最优雅的方式是什么?是_Noreturn int main(void)吗?

【问题讨论】:

  • 这是什么意思?为什么不直接使用int main(void)?它是标准的、可移植的和非 gcc 特定的。
  • @user694733 因为他使用的是准系统嵌入式系统,其中 1) int main (void) 没有任何意义 2) void main (void) 是 100% 标准和 100% 可移植的。 Read this.
  • (......然后人们继续对一些困惑的 PC 程序员的评论进行投票。希望你能对 cme​​ts 投反对票。)
  • 它是嵌入式的——谁在乎它是否永远不会返回。我根本不明白这种担心。这肯定不是问题吗?
  • @MartinJames 通常,裸机嵌入式系统从重置 ISR 开始执行,该 ISR 反过来又调用 main。如果 main 的调用约定是 int main(),那么重置 ISR 将为堆栈上的返回值腾出空间,即使 main() 永远不会返回。

标签: c language-lawyer


【解决方案1】:

您正在阅读标准的错误部分。 5.1.2.2.1 是5.1.2.2 托管环境的子条款。准系统嵌入式系统不是托管系统,它是独立系统。所以引用的文字是无关紧要的。更多信息here。

在独立环境中声明 main 的最便携方式是 void main (void)。

正如另一个答案中已经提到的,gcc 编译器选项是-ffreestanding

【讨论】:

    【解决方案2】:

    你的目标是矛盾的。您不能要求编译器标志不是特定于编译器的。

    也就是说,对于 gcc,它是:-ffreestanding。

    -ffreestanding

    Assert that compilation takes place in a freestanding environment.
     This implies `-fno-builtin'.  A freestanding environment is one in
     which the standard library may not exist, and program startup may
     not necessarily be at `main'.  The most obvious example is an OS
     kernel.  This is equivalent to `-fno-hosted'.
    

    【讨论】:

      【解决方案3】:

      您错过了短语“或以其他实现定义的方式”的结尾。因此,您的实现,即您的平台,而不是您作为程序员,可能会预见到main 的不同返回类型,而某些平台会这样做。

      同样根据 C99 和 C11,您不必为 main 指定返回值。当你从main返回时,该平台应该做合理的事情,如果你曾经这样做的话。

      在任何情况下,main 都是特殊的并且遵守特殊的规则。相信您的平台提供商,它会为它做正确的事情。您说的是完全可以忽略不计的优化,以防您的 main 真的永远不会返回。

      【讨论】:

      • 不,他读错了标准的章节。关于“实现定义的方式”这句话适用于托管系统中main的参数,因此它是完全不相关的。
      • @Lundin 您说得对,它适用于托管系统,但并非只适用于main 的参数。这就是为什么 5.1.2.2.3(仍然是 5.1.2.2 的一部分)以“如果主函数的返回类型是与 int 兼容的类型”开头的原因。
      • @hvd 5.1.2.2.3 以If the return type is not compatible with int, the termination status returned to the host environment is unspecified 结尾。 Unspecified 和 impl.defined 是两个不同的东西。这实际上可能是 C 标准中的不一致。 但是,这并不重要,因为这个问题与托管系统无关。
      • @Lundin 我没有发现任何不一致之处。 void main(void) 是否有效是实现定义的。如果它是有效的,一个程序使用它,并且程序通过从main 返回而停止,终止状态是未指定的。它们是两种不同的东西,所以一种可以是实现定义的,而另一种是未指定的。同意这个问题无关紧要,无论如何评论,因为它可能仍然感兴趣。
      • @lundin,不,我不认为它只适用于参数。整个短语以“应使用int.. 的返回类型定义” 开头,分号和“or”指的是它之前的整个短语。从后面使用的非大写字母可以看出,“:”不会终止短语。
      猜你喜欢
      • 2018-03-16
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 2017-03-05
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多