假设我有一个像这样的虚拟 C 函数:
void Dummy(uint64* dest, const size_t count)
{
for (size_t ii = 0; ii < count; ii += 8) {
*dest++ = (uint64)dest;
}
}
如果您查看编译器创建的内容,第一条指令将检查的值count
是否不为零。
Dummy(unsigned long*, unsigned long):
cbz x1, .LBB0_7
...
.LBB0_7:
ret
是否有一个属性可以放置,count
以表明该值保证永远不会为零,并且可以省略这种不必要的比较? 还有其他可以部署的编码风格吗?
将for
循环改为while
循环和其他形式似乎并不重要。编译器很聪明!
是的,我确实很关心这个小小的指令。😊
10
最佳答案
2
GCC 具有assume
以下属性:
void Dummy(uint64_t* dest, const size_t count)
{
__attribute__((assume(count != 0)));
for (size_t ii = 0; ii < count; ii += 8)
{
*dest++ = (uint64_t)dest;
}
}
然后支票就消失了。
2
-
4自 C++23 以来一直是标准。godbolt.org
–
-
1@FrançoisAndrieux 并非每个人都能将 C++23 用于项目中。
–
|
将表达式放在1/count
函数中的某个位置。除以零会导致未定义的行为。由于编译器可以假设 UB 永远不会发生,这意味着count
不能为零。
3
-
谢谢@Barmar。这很聪明,但我选择另一种方法。它看起来更简洁一些。
– -
1当然,尽管该解决方案特定于编译器,但理论上它应该适用于任何足够智能的优化器。
– -
实际上@Barmar,我必须使用的编译器似乎不支持该属性,所以我使用你的方法,用一个巨大的注释块来解释我正在做的事情。
–
|
–
–
–
–
–
|