c - 强制对 C 函数进行编译时评估?

标签 c gcc constants compiler-optimization

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

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

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

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

最佳答案

如果我在您的问题 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 版本 4.2.1(基于 Apple Inc. build 5658)(LLVM build 2336.11.00)”,它也适用于“gcc 版本 4.4.3(Ubuntu 4.4.3-4ubuntu5.1)” )”(然后需要 -O3)。

关于c - 强制对 C 函数进行编译时评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20762012/

相关文章:

c - 无锁队列中的内存屏障使用

c - 判断两个文件是否属于同一个卷

c - 错误 : unknown type name. 找不到头文件中定义的结构

c++ - 将指针转换为模板参数 : Comeau & MSVC compile, GCC 失败

c++ - GCC 会优化掉内联访问器吗?

c# - 如何在 C# designer.cs 代码中使用常量字符串?

c - 直到运行时才知道尺寸的二维数组

c++ - GCC 的矢量化失败

c++ - const 有效,但 constexpr 无效

php - PDO预定义常量中的 "integer"是什么?