相关疑难解决方法(0)

为什么Clang会优化此代码?

代码的目的是找到32位浮点位模式的总数,它代表0到1之间的值.在我看来这应该可行,但由于某种原因,Clang的汇编输出基本上相当于return 0;.

我使用-std=c++1y -Wall -Wextra -pedantic -O2和编译了Clang 3.3和Clang 3.4.1-std=c++1y -Wall -Wextra -pedantic -O3

Clang 3.4使用-O2和-O3优化一切.

Clang 3.3仅使用-O3优化一切.

通过"优化一切",我的意思是这是程序的汇编输出:

main:                                   # @main
    xorl    %eax, %eax
    ret
Run Code Online (Sandbox Code Playgroud)
#include <limits>
#include <cstring>
#include <cstdint>

template <class TO, class FROM>
inline TO punning_cast(const FROM &input)
{
    TO out;
    std::memcpy(&out, &input, sizeof(TO));
    return out;
}

int main()
{
    uint32_t i = std::numeric_limits<uint32_t>::min();
    uint32_t count = 0;

    while (1)
    {
        float n = punning_cast<float>(i);
        if(n >= 0.0f && n <= 1.0f) …
Run Code Online (Sandbox Code Playgroud)

c++ clang compiler-optimization

51
推荐指数
1
解决办法
3618
查看次数

在代码优化期间,C++ 11编译器能否将局部变量转换为右值?

有时将复杂或长表达式分成多个步骤是明智的(例如,第二个版本不是更清楚,但它只是一个例子):

return object1(object2(object3(x)));
Run Code Online (Sandbox Code Playgroud)

可以写成:

object3 a(x);
object2 b(a);
object1 c(b);
return c;
Run Code Online (Sandbox Code Playgroud)

假设所有3个类都实现了以rvalue作为参数的构造函数,第一个版本可能更快,因为临时对象被传递并可以移动.我假设在第二个版本中,局部变量被认为是左值.但是如果以后没有使用变量,那么C++ 11编译器是否会优化代码,因此变量被认为是rvalues,两个版本的工作方式完全相同?我最感兴趣的是Visual Studio 2013的C++编译器,但我也很高兴知道GCC编译器在这个问题上的行为.

谢谢,米哈尔

c++ compiler-optimization rvalue-reference visual-c++ c++11

26
推荐指数
4
解决办法
2092
查看次数

何时重载通过引用(l值和r值)优先传递给值?

我已经看到它说一个operator=带有相同类型by-value的参数的文件在C++ 11中既作为复制赋值运算符又作为移动赋值运算符:

Foo& operator=(Foo f)
{
    swap(f);
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

替代方案的重复次数将超过两倍,并且可能出现错误:

Foo& operator=(const Foo& f)
{
    Foo f2(f);
    swap(f2);
    return *this;
}

Foo& operator=(Foo&& f)
{
    Foo f2(std::move(f));
    swap(f2);
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

在什么情况下,ref-to-const和r-value重载优先通过值,或何时需要?我正在考虑std::vector::push_back,例如,它被定义为两个重载:

void push_back (const value_type& val);
void push_back (value_type&& val);
Run Code Online (Sandbox Code Playgroud)

在第一个示例中,pass by value 用作复制赋值运算符和移动赋值运算符,无法push_back在Standard中定义为单个函数?

void push_back (value_type val);
Run Code Online (Sandbox Code Playgroud)

c++ overloading assignment-operator copy-and-swap c++11

24
推荐指数
1
解决办法
1945
查看次数

分配内存然后释放是否构成C++程序的副作用?

受此问题的启发,关于编译器是否可以优化掉对函数的调用而没有副作用.假设我有以下代码:

delete[] new char[10];
Run Code Online (Sandbox Code Playgroud)

它没有任何用处.但它有副作用吗?堆分配后立即释放被认为是副作用吗?

c++ memory memory-management

11
推荐指数
1
解决办法
396
查看次数

Clang真的很聪明吗?

如果我使用Clang 3.3编译以下代码,-O3 -fno-vectorize即使删除了注释行,也会得到相同的汇编输出.代码类型将所有可能的32位整数置于浮点数并计算[0,1]范围内的值.Clang的优化器实际上是否足够聪明,以致当被处理为浮点数时0xFFFFFFFF不在[0,1]的范围内,所以忽略fn完全的第二次调用?删除第二个调用时,GCC会生成不同的代码.

#include <limits>
#include <cstring>
#include <cstdint>

template <class TO, class FROM>
inline TO punning_cast(const FROM &input)
{
    TO out;
    std::memcpy(&out, &input, sizeof(TO));
    return out;
}

int main()
{
    uint32_t count = 0;

    auto fn = [&count] (uint32_t x) {
        float f = punning_cast<float>(x);
        if (f >= 0.0f && f <= 1.0f)
            count++;
    };

    for(uint32_t i = 0; i < std::numeric_limits<uint32_t>::max(); ++i)
    {
        fn(i);
    }
    fn(std::numeric_limits<uint32_t>::max()); //removing this changes nothing

    return count;
}
Run Code Online (Sandbox Code Playgroud)

见这里: …

c++ llvm clang compiler-optimization c++11

8
推荐指数
1
解决办法
614
查看次数

移动构造函数和初始化列表

我想为某个类型实现移动构造函数(没有复制构造函数),该类型需要是一个值类型boost::unordered_map.我们称之为这种类型Composite.

Composite 有以下签名:

struct Base
{
  Base(..stuff, no default ctor) : initialization list {}
  Base(Base&& other) : initialization list {} 
}

struct Composite
{
  Base member;
  Composite(..stuff, no default ctor) : member(...) {}
  Composite(Composite&& other) : member(other.member) {} // <---- I want to make sure this invokes the move ctor of Base
}
Run Code Online (Sandbox Code Playgroud)

我想写这个,所以boost::unordered_map< Key , Composite >不需要复制构造函数,只需使用移动构造函数.如果可能的话,我不想Base在移动构造函数的初始化列表中使用复制构造函数Composite.

这可能吗?

c++ unordered-map initialization move-semantics c++11

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

在构造函数初始化列表上移动shared_ptr

最近我看到了几个这样的代码示例,其中std :: move用于构造函数初始化列表(不是移动构造函数).

class A {
public:
    A(std::shared_ptr<Res> res) : myRes(std::move(res)) {
    // ...
    }

private:
    std::shared_ptr<Res> myRes;
}
Run Code Online (Sandbox Code Playgroud)

我得到的信息是这个结构是出于优化原因.我个人使用std :: move尽可能少见.我威胁他们作为演员(如Scott Meyers所说),并且只在调用者代码中(只有例外是移动构造函数).对我来说,它看起来像某种混淆或微观优化,但也许我错了.是不是真的,如果没有std :: move,编译器不会产生更快的代码?

c++ optimization move move-semantics c++11

5
推荐指数
1
解决办法
914
查看次数

C++:std :: move with rvalue reference不是移动内容

示例程序:

#include <iostream>
#include <string>
#include <vector>

template <typename T>
void print(const T& _vec)
    {        
        for( auto c: _vec )
            std::cout << c << ",";
    }

typedef std::vector<std::string> vecstr_t;

struct Trade
{
    explicit Trade(vecstr_t&& vec) : _vec(vec )
    {       
    }  

     vecstr_t _vec;
};


int main()
{   
    vecstr_t tmpV = {"ONE", "TWO", "THREE", "FOUR"};    
    std::cout << "size 1:" << tmpV.size() << "\t"; print(tmpV); std::cout <<  "\n" ;    
    Trade t(std::move(tmpV));    
    std::cout << "size 2:" << tmpV.size() << "\t";  print(tmpV); std::cout <<  "\n" …
Run Code Online (Sandbox Code Playgroud)

c++ move move-semantics c++11

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

如果没有数据发送到 std::ofstream,如何避免创建文件?

当 C++ 创建std::ofstream它时,它立即并隐式创建底层文件。

我完全同意这种行为,除非我有一个代码,只有在运行期间才能看到是否会产生任何数据。

因此,我想避免在没有数据发送给空文件时创建空文件(事务完整性:没有数据,文件系统上没有更改)。

我看到两种我不太喜欢的方法:

  1. 查看是否有内容发送到流 ( tellg()),如果流为空,则删除该文件。我不喜欢创建和删除文件(有时文件很多)并且remove操作本身承担了太多责任。
  2. 创建std::stringstream,收集输出并std::ofstream仅在字符串流不为空的情况下创建和复制内容。好多了,但仍然需要临时内存分配,这可能很大。

对此有更好的解决方案吗?我是否缺少一些想法?

以代码的形式:

#include <fstream>

int main()
{
    std::ofstream ofs("file.txt");

    // Some code that might or might not output to ofs
    // Some other code that might or might not output to ofs
    // Some more code that might or might not output to ofs

    // It would be nice if file is not created if no data sent to ofs
} …
Run Code Online (Sandbox Code Playgroud)

c++ std

0
推荐指数
1
解决办法
76
查看次数