相关疑难解决方法(0)

C++中的"重新绑定"引用是否合法?

C++中的以下内容是否合法?

据我所知,Reference有一个简单的析构函数,所以它应该是合法的.
但我认为参考不能合法反弹......可以吗?

template<class T>
struct Reference
{
    T &r;
    Reference(T &r) : r(r) { }
};

int main()
{
    int x = 5, y = 6;
    Reference<int> r(x);
    new (&r) Reference<int>(y);
}
Run Code Online (Sandbox Code Playgroud)

c++ reference placement-new language-lawyer

38
推荐指数
3
解决办法
1631
查看次数

究竟什么是C++中的"副作用"?

它是一个定义明确的标准术语,还是开发人员用来解释一个概念(......和概念是什么)的术语?据我所知,这与所有令人困惑的序列点有关,但我不确定.

我在这里找到了一个定义,但是这不会使每个代码语句产生副作用吗?

副作用是运算符,表达式,语句或函数的结果,即使在完成对运算符,表达式,语句或函数的求值之后,它仍然存在.

有人可以解释一下"副作用"一词在C++中的正式含义,它的意义是什么?

作为参考,有些问题涉及副作用:

  1. 逗号操作员是否没有副作用?
  2. 强制编译器不优化无副作用的语句
  3. 将对象传递给C++函数时的副作用

c++ c++11

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

具有从未实际执行的未定义行为的表达式是否会导致程序错误?

在关于未定义行为(UB)的许多讨论中,已经提出了这样的观点:在程序中存在任何具有UB的任何构造的程序都要求一致的实现做任何事情(包括什么都没有).我的问题是,即使在UB与代码执行相关联的情况下,是否应该采取这种方式,而标准中规定的行为(否则)规定不应执行相关代码(这可能是对于程序的特定输入;它可能在编译时不可判定).

更加非正式地说,UB的气味是否要求一致的实现来决定整个程序发臭,并且拒绝正确执行甚至行为完全明确定义的程序部分.一个示例程序将是

#include <iostream>

int main()
{
    int n = 0;
    if (false)
      n=n++;   // Undefined behaviour if it gets executed, which it doesn't
    std::cout << "Hi there.\n";
}
Run Code Online (Sandbox Code Playgroud)

为清楚起见,我假设程序格式正确(因此特别是UB与预处理无关).事实上,我愿意将UB限制为与"评估"相关联,而"评估"显然不是编译时实体.我认为,与给出的例子相关的定义(重点是我的):

之前排序的是由单个线程(1.10)执行评估之间的不对称,传递,成对关系,这导致这些评估之间的部分顺序

在运算符的结果的值计算之前,对运算符的操作数的值计算进行排序.如果对标量对象的副作用相对于...或使用相同标量对象的值进行值计算未被排序,则行为未定义.

隐含地清楚的是,最后一句中的主语"副作用"和"价值计算"是"评价"的实例,因为这就是定义"之前排序"的关系.

我认为在上述程序中,标准规定不进行评价,以满足最后一句中的条件(相对于彼此和所描述的类型),并且该程序不具有UB; 这不是错误的.

换句话说,我确信我的标题问题的答案是否定的.但是,我会很感激其他人对此事的(动机)意见.

对于那些主张肯定答案的人来说,可能还有一个问题是,当编译错误的程序时,会强制重新格式化硬盘吗?

本网站上的一些相关指针:

c++ undefined-behavior language-lawyer

19
推荐指数
3
解决办法
1117
查看次数

内存泄漏是否会导致未定义的行为?

另一篇文章的评论中提出了这个讨论.

示例代码:

#include <string>

void func()
{
    std::string* foo;
    foo = new std::string[125];

    throw 1;

    delete [] foo;
}

int main()
{
     try { func(); }
     catch(int x) {}
}
Run Code Online (Sandbox Code Playgroud)

该程序是否会导致未定义的行为?据称,根据§3.8p4,它是UB ,它是:

程序可以通过重用对象占用的存储来结束任何对象的生命周期,或者通过使用非平凡的析构函数显式调用类类型的对象的析构函数来结束任何对象的生命周期.对于具有非平凡析构函数的类类型的对象,程序不需要在重用或释放对象占用的存储之前显式调用析构函数; 但是,如果没有显式调用析构函数或者如果没有使用delete-expression(5.3.5)来释放存储,则不应该隐式调用析构函数,并且任何程序都依赖于析构函数产生的副作用有未定义的行为.

c++ undefined-behavior language-lawyer

18
推荐指数
0
解决办法
1110
查看次数

内存是否泄漏了C++中的"未定义行为"类问题?

事实证明,许多无辜的东西都是C++中未定义的行为.例如,一旦一个非空的指针已被delete"D 甚至在打印的是指针的值是未定义的行为.

现在内存泄漏肯定是坏事.但他们是什么类的情况 - 定义,未定义或其他类别的行为?

c++ memory-leaks memory-management undefined-behavior

14
推荐指数
5
解决办法
1898
查看次数

为什么不删除在C++ 11中具有带有副作用未定义行为的析构函数的对象?

这个答案引用了C++ 11 Standard 3.8:

如果没有对析构函数的显式调用或者如果没有使用delete-expression(5.3.5)来释放存储,则不应该隐式调用析构函数,并且任何依赖于析构函数产生的副作用的程序都没有被定义行为.

关于析构函数未被调用的部分很清楚.现在假设跳过的析构函数具有应该影响程序行为的副作用.

为什么程序行为现在未定义?为什么不跳过副作用(因为没有调用析构函数)并且程序正常运行而没有应用副作用?

c++ destructor memory-leaks undefined-behavior c++11

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

可以不在放置新分配的对象上调用析构函数吗?

说我有一个固定的内存缓冲区

char *buffer; 
Run Code Online (Sandbox Code Playgroud)

使用placement new在缓冲区中分配我的结构

struct S
{ 
    std::tuple<int, double, char> m_data; 
    auto getRecord() 
    { 
        return m_data;
    }
};

S *newS = new(buffer + offset)S; 
Run Code Online (Sandbox Code Playgroud)

我知道我应该手动调用这些已分配项目的析构函数,但是如果没有涉及bookeeping /资源管理,是否可以省略它?换句话说,如果使用缓冲区的类的析构函数没有执行任何操作(类似于~S()上面的内容),是否可以跳过此步骤?如果是这种情况,我可以重用缓冲区而不破坏以前的租户吗?

c++

7
推荐指数
2
解决办法
370
查看次数