相关疑难解决方法(0)

未调用函数会影响代码结果

在这里挠头。在下面的代码,则该函数f在3种不同的方式通过使用task_lambda()task_bind()task_thread()。在main()但是,只有功能task_lambda()task_bind()实际调用和执行。但是,如果您敢于取消注释#if 0代码块,以使未使用的功能task_thread()不再存在于代码中,则main中的代码现在将引发异常(-1)system_error。

这是代码:

#include <iostream>                                                                                                                                                                                         
#include <cmath>
#include <thread>
#include <future>
#include <functional>
#include <unistd.h>

// unique function to avoid disambiguating the std::pow overload set
int f(int x, int y) { return std::pow(x,y); }

void task_lambda()
{
    std::packaged_task<int(int,int)> task([](int a, int b) {
        return std::pow(a, b);
    }); 
    std::future<int> result = task.get_future();

    task(2, 9); 

    std::cout << "task_lambda:\t" << result.get() << '\n';
}

void …
Run Code Online (Sandbox Code Playgroud)

c++

6
推荐指数
1
解决办法
125
查看次数

clang 如何设法将具有未定义行为的代码编译成该机器代码?

这是此推文代码的变体,只是更短,不会对菜鸟造成任何损害。我们有这样的代码:

typedef int (*Function)();

static Function DoSmth;

static int Return7()
{
    return 7;
}

void NeverCalled()
{
   DoSmth = Return7;  
}

int main()
{
    return DoSmth();
}
Run Code Online (Sandbox Code Playgroud)

您会发现NeverCalled()代码中从未调用过它,不是吗?以下是选择 clang 3.8 时编译器资源管理器显示的内容

-Os -std=c++11 -Wall
Run Code Online (Sandbox Code Playgroud)

发出的代码是:

NeverCalled():
    retq
main:
    movl    $7, %eax
    retq
Run Code Online (Sandbox Code Playgroud)

就好像NeverCalled()之前实际调用过DoSmth()并将DoSmth函数指针设置为Return7()函数一样。

如果从内部删除函数指针分配,NeverCalled()如下所示:

void NeverCalled() {}
Run Code Online (Sandbox Code Playgroud)

那么发出的代码是这样的:

NeverCalled():
    retq
main:
    ud2
Run Code Online (Sandbox Code Playgroud)

后者是值得期待的。编译器知道函数指针肯定为空,并且使用空函数指针调用函数是未定义的行为。

前面的代码并不是真正所期望的。不知何故,编译器决定Return7()调用,尽管它没有在任何地方直接调用,并且函数指针赋值位于未调用的函数内部。

是的,我知道 C++ 标准允许面向具有未定义行为的代码的编译器执行此操作。它是如何做到这一点的呢?

clang 是如何发出这个特定的机器代码的?

c++ compilation clang compiler-optimization undefined-behavior

4
推荐指数
1
解决办法
445
查看次数