首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >创建一个总是返回零的函数,但是优化器不知道

创建一个总是返回零的函数,但是优化器不知道
EN

Stack Overflow用户
提问于 2018-07-23 13:11:01
回答 3查看 299关注 0票数 4

我想创建一个总是返回零的函数,但这一事实对于优化器来说不应该是显而易见的,这样使用该值的后续计算就不会因为“已知零”状态而不断折叠。

在缺乏链接时间优化的情况下,通常只需将此代码放入其自己的编译单元:

代码语言:javascript
复制
int zero() {
  return 0;
}

优化器不能看到所有的单元,所以这个函数始终为零的特性不会被发现。

然而,我需要一些与LTO和尽可能多的未来智能优化工作的东西。我考虑读一篇全球版的文章:

代码语言:javascript
复制
int x;

int zero() {
  return x;
}

..。但在我看来,一个足够聪明的编译器可以注意到x永远不会被写入,并且仍然决定zero()始终为零。

我考虑过使用volatile,比如:

代码语言:javascript
复制
int zero() {
  volatile int x = 0;
  return x;
}

..。但是,易失性读取所需副作用的实际语义并不完全清楚,并且似乎不排除函数仍然返回零的可能性。

这种始终为零但在编译时不为零的值在几种情况下都很有用,例如强制两个值之间存在无操作依赖关系。例如:a += b & zero()使a在最终的二进制文件中依赖于b,但不会更改a的值。

不要通过告诉我“标准不能保证任何方式来做到这一点”来回答这个问题--我很清楚,我正在寻找一个实用的答案,而不是标准中的语言。

EN

回答 3

Stack Overflow用户

发布于 2018-07-23 13:48:32

如果编译器能弄清楚这一点,我会很惊讶:

代码语言:javascript
复制
int not_a_zero_honest_guv()
{
    // static makes sure the initialization code only gets called once
    static int const i = std::ifstream("") ? 1:0;
    return i;
}

int main()
{
    std::cout << not_a_zero_honest_guv();
}

这使用了函数局部静态的复杂的(不可预测的)运行时初始化。如果顽皮的小编译器发现一个空的文件名总是会失败,那么就在里面放一些非法的文件名。

票数 2
EN

Stack Overflow用户

发布于 2018-07-23 14:09:31

你会发现每个编译器都有一个扩展来实现这一点。

GCC:

代码语言:javascript
复制
__attribute__((noinline))
int zero()
{
    return 0;
}

MSVC:

代码语言:javascript
复制
__declspec(noinline)
int zero()
{
    return 0;
}
票数 0
EN

Stack Overflow用户

发布于 2018-07-23 20:57:27

在clang和gcc中,敲打一个变量是可行的,但会增加一些开销

代码语言:javascript
复制
int zero()
{
    int i = 0;
    asm volatile(""::"g"(&i):"memory");
    return i;
}

在gcc的O3下被编译成

代码语言:javascript
复制
    mov     DWORD PTR [rsp-4], 0
    lea     rax, [rsp-4]
    mov     eax, DWORD PTR [rsp-4]
    ret

然后在当当

代码语言:javascript
复制
    mov     dword ptr [rsp - 12], 0
    lea     rax, [rsp - 12]
    mov     qword ptr [rsp - 8], rax
    mov     eax, dword ptr [rsp - 12]
    ret

Live

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51471889

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档