【问题标题】:C18: Will the compiler "know" a function call will never return?C18:编译器会“知道”函数调用永远不会返回吗?
【发布时间】:2013-03-08 17:18:06
【问题描述】:

我正在使用 C18 在 PIC18 上构建 16 状态 FSM。我正在考虑将每个状态作为自己的函数,它会跳转到其他状态并被其他状态跳转。我很想在每个状态的末尾写一个“state##();”的分支案例来确定程序应该去哪里,但我认为这会很快死掉,因为编译器可能会期望这个回归,而不是永远的分支;我的微控制器上的堆栈会很快填满并最终溢出。

C18 是否足够聪明,知道我的函数调用永远不会返回并相应地用 GOTO/JMP 而不是 CALL/BRANCH 替换指令?我知道 GOTO 存在于 C 中(出于可读性原因,通常强烈建议不要这样做),但我想不出比这里更合适的理由来使用它。我知道我可以强制它使用 _asm _endasm 块转到,但如果没有必要,我会为自己省去麻烦。用 C 语言说去一个函数并且永远不会回来的最好方法是什么?

当然,感谢所有帮助

【问题讨论】:

  • 对于这样的问题没有通用的答案,有些编译器会有些编译器不会。通常编译器有一个命令行选项来生成汇编程序而不是目标代码。 (例如,对于 gcc,这是 -S)。检查那个汇编器,你就会知道。现代 C aka C11 甚至有一个关键字可以让您指定:_Noreturn
  • IMO 最好的办法就是不用担心。你想保存什么?内存使用只是一个微不足道的优化。
  • 我很确定我必须担心它。如果编译器使用“调用”,那么当我沿着 fsm 移动并且永远不会返回时,它会一直保存程序计数器。 Goto 不会将程序计数器保存在堆栈中,因此我不必担心溢出。

标签: c microcontroller pic mplab c18


【解决方案1】:

您所说的似乎是某种递归设计,这是函数调用不断堆积的唯一方式。我认为您对状态机的工作方式没有正确的想法。尝试看一下这个 C 语言 FSM 的绝佳模板:

C state-machine design

如果您想发布一些示例代码或您对实现它的想法,我们可以提供更多帮助。

【讨论】:

  • 是的,将每个状态作为一个函数并不是最好的思考方式。 while 循环和 case 切换要容易得多。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
  • 2017-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-18
  • 2017-07-13
相关资源
最近更新 更多