我有以下测试代码:
#include <cstdint>#include <cassert>enum class Result : std::uint32_t {SUCCESS = 0,INSUCCESS = 1};voID* func(Result& result){ // works great /* result = Result::INSUCCESS; return NulL; */ // error: invalID conversion from ‘long int’ to ‘voID*’ [-fpermissive] /* return result = Result::INSUCCESS,NulL; */ // compiles,but <result> is not set??? return result = Result::INSUCCESS,nullptr;}voID testReturnWithSIDeEffects(){ Result result = Result::SUCCESS; func(result); assert(result == Result::INSUCCESS);}
这里有两个问题但我对第二个问题最感兴趣:
为什么没有设置结果?
编辑:
感谢大家的确认.我决定使用的解决方法是替换:
return result = Result::INSUCCESS,nullptr;
以下内容:
return result = Result::INSUCCESS,(voID*)NulL;
附加说明:当然我的生产场景是另一种指针类型(不是voID *),但为了说明的目的我进行了简化.
另一个注意事项:从解决方法中你可以看出,这个nullptr有一些可疑的东西.我猜测不编译的示例行应该实际编译,并且这两个问题可能以某种方式相关.
和第三和最后一点,那些谁介绍的“挂羊头卖狗肉”或者我的代码“不可读性”:可读性在很大程度上是一个主观的问题,比如我可以说,这样的简写可以使代码更有条理这实际上可以帮助现货缺陷.
解决方法 第二种情况:return result = Result::INSUCCESS,nullptr;
看起来像一个gcc BUG,如果我将return语句更改为this(see it live),它似乎在return语句的上下文中忽略了逗号运算符的左侧:
return (printf("hello\n"),nullptr);
没有输出,但如果我们在return语句之外执行此 *** 作,则会得到预期结果.它看起来固定在4.8但我可以用4.6和4.7重现.
如果我们看一下draft C++ standard部分5.18 Comma运算符,它说(强调我的):
A pair of @R_301_3725@s separated by a comma is evaluated left-to-right; the left @R_301_3725@ is a discarded value @R_301_3725@ (Clause 5).83 Every value computation and sIDe effect associated with the left @R_301_3725@ is sequenced before every value computation and sIDe effect associated with the right @R_301_3725@. The type and value of the result are the type and value of the right operand; the result is of the same value category as its right operand,and is a bit-fIEld if its right operand is a glvalue and a bit-fIEld. If the value of the right operand is a temporary (12.2),the result is that temporary.
无论如何,正如几个人已经提到的那样,这段代码很聪明但难以阅读,因此难以维护,将其拆分为两行也能正常工作.我总是想记住这个quote from Brian Kernighan(可能还有其他几个版本):
Everyone kNows that deBUGging is twice as hard as writing a program in the first place. So if you’re as cLever as you can be when you write it,how will you ever deBUG it?
对于第一种情况,如果我们查看4.10节指针转换(错过我的未来),则错误是有效的:
A null pointer constant is an integral constant @R_301_3725@ (5.19)
prvalue of integer type that evaluates to zero or a prvalue of type
std::nullptr_t. A null pointer constant can be converted to a pointer
type; the result is the null pointer value of that type and is
distinguishable from every other value of object pointer or function
pointer type. Such a conversion is called a null pointer conversion.
表达方式:
result = Result::INSUCCESS,NulL
不是一个常量表达式,因为它包含=,5.19常量表达式中包含什么是常量表达式,并说:
A conditional-@R_301_3725@ is a core constant @R_301_3725@ unless it
involves one of the following as a potentially evaluated sub@R_301_3725@
(3.2) […]
包括:
an assignment or a compound assignment (5.17); or
使用nullptr是可以的,因为它是std :: nullptr_t的prvalue,我们可以从12.14.7节指针文字看到:
总结The pointer literal is the keyword nullptr. It is a prvalue of type std::nullptr_t. [ Note: std::nullptr_t is a distinct type that is neither a pointer type nor a pointer to member type; rather,a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value. See 4.10 and4.11. —endnote]
以上是内存溢出为你收集整理的c – 逗号运算符,return语句和nullptr没有副作用?全部内容,希望文章能够帮你解决c – 逗号运算符,return语句和nullptr没有副作用?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)