相关疑难解决方法(0)

"C++编程语言"第4版第36.3.6节中的代码是否有明确定义的行为?

在Bjarne Stroustrup的"C++编程语言"第4版36.3.6 STL类操作部分中,以下代码用作链接示例:

void f2()
{
    std::string s = "but I have heard it works even if you don't believe in it" ;
    s.replace(0, 4, "" ).replace( s.find( "even" ), 4, "only" )
        .replace( s.find( " don't" ), 6, "" );

    assert( s == "I have heard it works only if you believe in it" ) ;
}
Run Code Online (Sandbox Code Playgroud)

断言失败gcc(看到它直播)和Visual Studio(看到它的实时),但它在使用Clang时没有失败(请参见实时).

为什么我会得到不同的结果?这些编译器是否错误地评估了链接表达式,或者此代码是否表现出某种形式的未指定 …

c++ operator-precedence language-lawyer unspecified-behavior c++11

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

C++ 17引入了哪些评估顺序保证?

在典型的C++代码中,C++ 17评估顺序保证(P0145)投票的含义是什么?

对于像这样的事情,它有什么变化

i=1;
f(i++, i)
Run Code Online (Sandbox Code Playgroud)

std::cout << f() << f() << f() ;
Run Code Online (Sandbox Code Playgroud)

要么

f(g(),h(),j());
Run Code Online (Sandbox Code Playgroud)

c++ operator-precedence c++17

77
推荐指数
2
解决办法
7130
查看次数

尽管在右侧有例外,但C++中的赋值仍然发生

我有一些(C++ 14)代码,如下所示:

map<int, set<string>> junk;
for (int id : GenerateIds()) {
    try {
        set<string> stuff = GetStuff();
        junk[id] = stuff;
    } catch (const StuffException& e) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

这有效.有时GetStuff()抛出一个异常,这很好,因为如果它,我不想在垃圾地图中的值.

但起初我在循环中写了这个,这不起作用:

junk[id] = GetStuff();
Run Code Online (Sandbox Code Playgroud)

更确切地说,即使GetStuff()抛出异常,junk[id]也会创建(并分配一个空集).

这不是我所期望的:我希望它们以相同的方式运行.

我在这里误解了C++的原理吗?

c++ c++14

72
推荐指数
3
解决办法
4065
查看次数

首先处理赋值表达式的哪一侧?

考虑以下代码:

std::unordered_map<int, std::string> data;
data[5] = foo();
Run Code Online (Sandbox Code Playgroud)

按照什么顺序data[5]foo()处理?如果foo()抛出异常,是否创建了5项目data

如果行为取决于C++的版本,那些版本有何不同?

c++ exception-handling stdmap

14
推荐指数
0
解决办法
282
查看次数

为什么 std::unique_ptr&lt;&gt;.release() 在赋值左侧的成员函数访问之前被评估?

当访问 unique_ptr->get_id() 时,这会导致分段错误,因为 release() 是预先运行的。

这里不保证顺序吗?

#include <iostream>
#include <memory>
#include <unordered_map>

class D
{
private:
        int id_;
public:
        D(int id) : id_{id} { std::cout << "D::D\n"; }
        ~D() { std::cout << "D::~D\n"; }

        int get_id() { return id_; }

        void bar() { std::cout << "D::bar\n"; }
};

int main() {
        std::unordered_map<int, D*> obj_map;
        auto uniq_ptr = std::make_unique<D>(123);

        obj_map[uniq_ptr->get_id()] = uniq_ptr.release();
        obj_map.at(123)->bar();

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

c++ c++20

9
推荐指数
2
解决办法
881
查看次数

如何在函数参数初始化中捕获未定义的行为

以下代码在clang ++中有效,但在g ++中崩溃了

#include<vector>
#include<iostream>

template<class Iterator>
double abs_sum(double current_sum, Iterator it, Iterator it_end){
    if (it == it_end)
        return current_sum;
    return abs_sum(current_sum+std::abs(*it),++it,it_end);
}


int main(int argc, char** argv){
    std::vector<double> values {1.0, 2.0,-5};

    std::cout << abs_sum(0.0,values.begin(),values.end()) << std::endl;;
}
Run Code Online (Sandbox Code Playgroud)

罪魁祸首证明是这条线:

return abs_sum(current_sum+std::abs(*it),++it,it_end);
Run Code Online (Sandbox Code Playgroud)

在clang中,*it在之前进行评估++it,在g ++中它是相反的,导致迭代器在被解除引用之前被增加.事实证明,评估函数参数的顺序是实现定义的.

我的问题是:我如何捕获此类错误?理想情况下,当我意外地依赖于具体实施细节时,我想要出错或至少发出警告.

即使用-Wall,clang和gcc都不会发出任何警告.

c++ undefined-behavior unspecified-behavior

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

C++ evaluation order and sequenced before and compiler reorder?

I've read from Order of evaluation, and I don't understand it well. Does the order mean the execution order in run time or just the logic order in the source code?

Let's see a code snippet as below:

void f()
{
   int a = 10; // A
   int b = 20; // B
   //...
}
Run Code Online (Sandbox Code Playgroud)

Does it mean that expression A is sequenced before expression B?

And is the c++ compiler allowed to reorder the code as below? …

c++ c++11

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