c – 逗号运算符,return语句和nullptr没有副作用?

c – 逗号运算符,return语句和nullptr没有副作用?,第1张

概述参见英文答案 > gcc nullptr issue                                    1个 我有以下测试代码: #include <cstdint>#include <cassert>enum class Result : std::uint32_t {SUCCESS = 0, INSUCCESS = 1};void* func(Result& re 参见英文答案 > gcc nullptr issue1个
我有以下测试代码:
#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没有副作用?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1243073.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存