Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这是否得到了优化?_C++_C_Optimization - Fatal编程技术网

C++ 这是否得到了优化?

C++ 这是否得到了优化?,c++,c,optimization,C++,C,Optimization,我的断言宏如下所示: #ifdef DEBUG #define ASSERT(x) ((void)(!(x) && assert_handler(#x, __FILE__, __LINE__) && (exit(-1), 1))) #else #define ASSERT(x) ((void)sizeof(x)) 我认为这或多或少是防弹的,但我似乎经常在断言函数的返回值时使用它,这些函数对它们的副作用很重要。如果在我的发布版本中,我最终编译 ASSERT(fg

我的断言宏如下所示:

#ifdef DEBUG
#define ASSERT(x) ((void)(!(x) && assert_handler(#x, __FILE__, __LINE__) && (exit(-1), 1)))
#else 
#define ASSERT(x) ((void)sizeof(x))
我认为这或多或少是防弹的,但我似乎经常在断言函数的返回值时使用它,这些函数对它们的副作用很重要。如果在我的发布版本中,我最终编译

ASSERT(fgets(buffer,sizeof(buffer)/sizeof(buffer[0]),file));
那会变成什么

((void)sizeof(fgets(buffer,sizeof(buffer)/sizeof(buffer[0]),file)));

这是否有可能得到完全优化?我相当肯定它不会(我正在调用一个函数,
fgets
),但确保它的具体条件是什么?是否存在优化器可能会抛出的具有副作用的操作?

assert的通常含义是要优化掉,因此最好坚持这些语义并执行

#else 
#define ASSERT(x)
#endif
如果你坚持不优化它,为什么不这样做呢

#else 
#define ASSERT(x) ((void)(x))
#endif

assert的通常含义是要优化掉,所以最好还是坚持这些语义并执行

#else 
#define ASSERT(x)
#endif
如果你坚持不优化它,为什么不这样做呢

#else 
#define ASSERT(x) ((void)(x))
#endif

?它与优化无关。计算
sizeof
表达式的值时,永远不会计算操作数。比如说,

char func(void) { exit(1); }

size_t sz = sizeof(func());
// same as
size_t sz = 1;

如果你想在不产生编译器警告的情况下保留副作用,你可以像Neil G在他的回答中指出的那样,强制转换到
void

这与优化无关。计算
sizeof
表达式的值时,永远不会计算操作数。比如说,

char func(void) { exit(1); }

size_t sz = sizeof(func());
// same as
size_t sz = 1;

如果您想在不生成编译器警告的情况下保留副作用,您可以将其强制转换为
void
,正如Neil G在他的回答中所指出的那样。

通常,您编写断言是为了使它们没有任何副作用,因此可以删除。在自己的行上执行
fgets
,保存结果,然后使用
assert(result!=NULL)
。然后定义非调试
断言
以丢弃
x
。或者当我们在做的时候,stdlib中不是有一个
assert
。我现在觉得自己很傻。拥有自己的断言很好,因为它在调试器中很容易跟踪,而不是从某个CRT中弹出,而且我可以控制它的行为(特定于应用程序的警报?stderr?被动?中止程序?)。所谓的“带有副作用的断言”有时被称为“验证”,因此您可以这样命名宏。“assert”通常被理解为不需要作为程序逻辑的一部分。我试图用一个好词来描述它,“verify”符合要求。谢谢。通常,你写断言是为了使它们没有任何副作用,因此可以删除。在自己的行上执行
fgets
,保存结果,然后使用
assert(result!=NULL)
。然后定义非调试
断言
以丢弃
x
。或者当我们在做的时候,stdlib中不是有一个
assert
。我现在觉得自己很傻。拥有自己的断言很好,因为它在调试器中很容易跟踪,而不是从某个CRT中弹出,而且我可以控制它的行为(特定于应用程序的警报?stderr?被动?中止程序?)。所谓的“带有副作用的断言”有时被称为“验证”,因此您可以这样命名宏。“assert”通常被理解为不需要作为程序逻辑的一部分。我试图用一个好词来描述它,“verify”符合要求。谢谢。为什么不简单地定义ASSERT(x)x呢?@yi\u H:当然。我想这样,您就显式地丢弃了返回值,因此没有人可以编写
if(ASSERT(x))…
许多想法都来自于此:似乎我需要重新评估如何使用这些宏。也许我应该使用不同版本的断言。@yi_H:该定义将生成编译器警告。更具体地说,
sizeof
的确切原因是,它会抑制“已声明但未引用的变量”类型警告。规范的
int r=func();assert(r==OK)
当使用
时#定义assert(x)
来优化它会使r挂起。我使用
sizeof
技巧作为一个未使用的宏:
#define unused(x)((void)sizeof(x))
所以在编译发布时ASSERT变得未使用(没有生成指令,没有警告)为什么不简单地
#define ASSERT(x)x
?@yi H:当然。我想这样,您就显式地丢弃了返回值,因此没有人可以编写
if(ASSERT(x))…
许多想法都来自于此:似乎我需要重新评估如何使用这些宏。也许我应该使用不同版本的断言。@yi_H:该定义将生成编译器警告。更具体地说,
sizeof
的确切原因是,它会抑制“已声明但未引用的变量”类型警告。规范的
int r=func();assert(r==OK)
当使用
时#定义assert(x)
来优化它会使r挂起。我将
sizeof
技巧用作未使用的宏:
#定义未使用的(x)((void)sizeof(x))
因此,在编译用于releaseSizeof时,ASSERT变为未使用的(没有生成指令,没有警告),而不必在编译时计算sizeof。例如,
size_t func(int x){int a[x];return sizeof(a);}
.sizeof不一定在编译时计算。例如,
size_t func(intx){inta[x];返回sizeof(a);}