注意:我见过类似的问题,但没有一个答案是准确的,所以我自己也会这样问.
C++标准说:
程序可以通过重用对象占用的存储来结束任何对象的生命周期,或者通过使用非平凡的析构函数显式调用类类型的对象的析构函数来结束任何对象的生命周期.对于具有非平凡析构函数的类类型的对象,程序不需要在重用或释放对象占用的存储之前显式调用析构函数; 但是,如果没有对析构函数的显式调用或者如果没有使用delete-expression来释放存储,则不应该隐式调用析构函数,并且任何依赖于析构函数产生的副作用的程序都有未定义的行为.
我根本不明白"取决于副作用"是什么意思.
一般问题是:
举例说明我的观点是:
考虑下面这样的程序.还要考虑明显的变化(例如,如果我不在另一个上构造一个对象,但我仍然忘记调用析构函数,如果我不打印输出来观察它,等等):
#include <math.h>
#include <stdio.h>
struct MakeRandom
{
int *p;
MakeRandom(int *p) : p(p) { *p = rand(); }
~MakeRandom() { *p ^= rand(); }
};
int main()
{
srand((unsigned) time(NULL)); // Set a random seed... not so important
// In C++11 we could use std::random_xyz instead, that's not the point
int x = 0;
MakeRandom *r = …Run Code Online (Sandbox Code Playgroud) 我在C++ 11中经历了关于Undefined Behavior和Sequenced [Before/After]关系的优秀答案.我理解二元关系概念,但我不知道管理测序的新规则是什么.
对于这些熟悉的示例,新的排序规则如何应用?
i = ++i;a[++i] = i;更具体地说,新的C++ 11排序规则是什么?
我正在寻找一些规则(这个是完全组成的)
在
lhs一个的'='语句总是前的测序rhs,并且首先是这样评价.
如果这些标准本身可用,有人可以在这里引用相同的内容吗?
我正在阅读一些旧的游戏编程书籍,正如你们中的一些人可能知道的那样,在那一天,做一些黑客攻击通常比以标准方式做事更快.(转换float为int,屏蔽符号位,转换回绝对值,而不是仅调用fabs(),例如)
现在,使用标准库数学函数几乎总是更好,因为这些微小的东西无论如何都不是大多数瓶颈的原因.
但为了好奇,我仍然想做一个比较.所以我想确保在我描述时,我没有得到偏差的结果.因此,我想确保编译器不会优化没有副作用的语句,例如:
void float_to_int(float f)
{
int i = static_cast<int>(f); // has no side-effects
}
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?据我所知,做类似的事情i += 10仍然没有副作用,因此无法解决问题.
我唯一能想到的是拥有一个全局变量int dummy;,并且在执行类似的操作之后dummy += i,所以使用了值i.但我觉得这个虚拟操作会妨碍我想要的结果.
我正在使用Visual Studio 2008/G ++(3.4.4).
为了澄清,我希望最大限度地优化所有优化,以获得良好的个人资料结果.问题在于,由此可以优化出没有副作用的陈述,因此情况就是如此.
为了再次澄清,请阅读:我不是试图在某种生产代码中对其进行微观优化.
我们都知道旧的技巧不再有用了,我只是好奇他们是多么有用.只是好奇心.当然,如果不知道这些旧的黑客对现代CPU的表现如何,生活可以继续下去,但要知道它永远不会伤害.
所以告诉我"这些技巧不再有用了,不要试图微观优化等等"是一个完全忽略这一点的答案.我知道它们没用,我不使用它们.
过早引用Knuth是所有烦恼的根源.
例如,对于这样的陈述:
c += 2, c -= 1
Run Code Online (Sandbox Code Playgroud)
是否真的首先总是评估c + = 2,而第二个表达式c- = 1中的c将始终是表达式c + = 2的更新值?
我在C++ : The Complete Reference书中读到以下内容
即使通过普通的按值调用参数传递机制将对象传递给函数,理论上它们可以保护和隔离调用参数,但是仍然可能发生可能影响甚至损坏的副作用,用作参数的对象.例如,如果用作参数的对象分配内存并在销毁时释放该内存,那么在调用析构函数时,函数内部的本地副本将释放相同的内存.这将使原始物体损坏并且实际上无用.
我真的不明白副作用是如何发生的.有人能通过一个例子来帮助我理解这一点吗?
我知道,如果我没有释放分配的内存删除/免费我最终会有内存泄漏.我的问题是:如果我的程序被终止,操作系统是否会为我释放内存,即使我没有?
编译器可以在多线程程序上下文中优化静态存储对象吗?我问它是否知道例如声明为静态的变量在线程中调用的函数中使用时是否会产生副作用。
bool flag = false; // static storage duration object
void f(){ //function called in a thread
flag = false;
// do some work...
flag = true;
}
//a possible representation of the code above after optimization
void f(){
flag = true;
// do some work...
} // is this possible to happen?
Run Code Online (Sandbox Code Playgroud)
我从这里阅读了一些答案,但没有找到任何可以帮助的内容。
根据5/1(标准):
表达式可能会导致值,并可能导致副作用.
显然我们有两种可能的选择:
1)表达导致一个值并导致副作用
2)表达产生一个值,不会引起副作用
还有哪些其他选择?(例如,是否存在任何不会产生值
的表达式?)我想到了带有void返回类型的throw-expression和函数.我们可以将它们引用到第一类或第二类(void具有可能副作用的类型的值)吗?
c++ ×8
c++11 ×2
destructor ×2
c ×1
deep-copy ×1
expression ×1
malloc ×1
memory ×1
optimization ×1
side-effects ×1