【问题标题】:Force compile time evaluation of a C function?强制对 C 函数进行编译时评估?
【发布时间】:2013-12-24 13:42:21
【问题描述】:

在我的微控制器项目中,我有一个更新 CRC 的功能(来自 avr-libc 的_crc_ibutton_update)。 我正在实现的协议计算数据包的校验和,包括其初始同步字节,我想将同步字节的 CRC 值保持为编译时间常数,但我不喜欢手动预先计算它。

有没有办法强制编译器(GCC 4.3.3)在编译时计算值并只发出一条加载常量指令?

库中的函数仅包含内联汇编程序,因此我尝试在参数为常量时使用 C 实现(使用 __builtin_constant_p() 确定)。代码只是正常编译。 CRC函数并不太复杂,只包含一个迭代次数恒定的for循环,一个分支和几个位操作。

需要说明的是,保存这 8 个汇编指令绝对不是关键,但找到某种解决方案对于我的强迫症来说将是一份不错的圣诞礼物 :-)

【问题讨论】:

  • C++ 和嵌入式编程是朋友多于敌人的另一个原因。
  • 你是否制作了你为static inline目的编写的C函数?
  • "强制对 C 函数进行编译时评估?" - 我就是这样做的:gcc -O3 -c foo.c

标签: c gcc constants compiler-optimization


【解决方案1】:

如果我在您的问题static inline 中声明超链接后面的函数,那么gcc -O3 会将已知参数上的函数调用编译为单个指令:

~ $ cat t.c
#include <stdint.h>

static inline uint8_t
 _crc_ibutton_update(uint8_t crc, uint8_t data)
{
  uint8_t i;

  crc = crc ^ data;
  for (i = 0; i < 8; i++)
    {
      if (crc & 0x01)
    crc = (crc >> 1) ^ 0x8C;
      else
    crc >>= 1;
    }

  return crc;
}

int x;

int main()
{
  x = _crc_ibutton_update(17, 42);
}
~ $ gcc -O2 -S t.c
~ $ cat t.s
...
    movq    _x@GOTPCREL(%rip), %rax
    movl    $158, (%rax)
    popq    %rbp
    ret
...

这适用于“gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)”,它也适用于“gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1) )”(然后需要-O3)。

【讨论】:

    【解决方案2】:

    有办法,但必须升级到C++11!

    新的constexpr 说明符正是您所看到的。但遗憾的是,它是not supported in GCC 4.3

    【讨论】:

    • 他没有要求 c++
    猜你喜欢
    • 2012-02-01
    • 2012-12-24
    • 1970-01-01
    • 2022-08-17
    • 2020-08-22
    • 1970-01-01
    • 2021-02-13
    • 2015-08-02
    • 2012-12-26
    相关资源
    最近更新 更多