C++标准在3.3.2“声明点”中包含了一个半著名的“令人惊讶的”名称查找示例:
int x = x;
这会用它自己初始化x
,它(作为一个基元类型)是未初始化的,因此具有一个不确定的值(假设它是一个自动变量)。
更新:在评论中的讨论之后,我在这个答案的末尾添加了一些更多的证据。
免责声明:我承认这个答案是相当投机的。另一方面,目前C++11标准的制定似乎不允许有一个更正式的答案。
在本问答的上下文中,C++11标准没有正式规定每个语言结构所期望的值类别。在下面,我将主要关注内置运算符,尽管问题是关于初始化器的。最后,我将把我在运算符的情况下得出的结论扩展到初始化器的情况。
因此,函数调用不应在LValue到RValue的转换和与任何单个复合赋值运算符相关联的副作用之间进行干预
当然,如果没有预期的rvalue,这个注释将毫无意义。
另一个证据在4/8中找到,正如约翰内斯·肖布在链接问答的评论中指出的那样:
通常的lvalue到rvalue(4.1)、数组到指针(4.2)和函数到指针(4.3)标准转换是不需要的,因此,当直接绑定到lvalue时,这些转换被禁止。
“通常”这个词似乎意味着,当初始化不属于引用类型的对象时,应该应用lvalue-to-rvalue转换。
因此,我认为,尽管对初始值设定项的期望值类别的要求不明确(如果不是完全缺失的话),但根据所提供的证据,假设预期的规范如下是有意义的:
补充证据:
为了提供进一步的证据来支持这一猜想,让我们假设它是错误的,因此复制初始化确实不需要LValue到RValue的转换,并考虑以下代码(感谢jogojapan的贡献):
int y;
int x = y; // No UB
short t;
int u = t; // UB! (Do not like this non-uniformity, but could accept it)
int z;
z = x; // No UB (x is not uninitialized)
z = y; // UB! (Assuming assignment operators expect a prvalue, see above)
// This would be very counterintuitive, since x == y
这种不统一的行为对我来说没有太多意义。IMO更有意义的是,只要需要一个值,就需要一个prvalue。
关于第二个问题,正如答案的最初部分所讨论的,C++11标准目前没有指定是否需要类别转换,因为没有提到复制初始化是否需要prvalue作为初始值设定项。因此,不可能给出明确的答案。然而,我相信我提供了足够的证据来假设这是预期的规范,所以答案将是“是”。
至于第一个问题,在我看来,答案也是“是”是合理的。如果是“不”,显然正确的程序将是错误的:
int y = 0;
int x = y; // y is lvalue, prvalue expected (assuming the conjecture is correct)
概括起来(A1=“回答问题1”,A2=“回答问题2”):
| A2 = Yes | A2 = No |
---------|------------|---------|
A1 = Yes | UB | No UB |
A1 = No | ill-formed | No UB |
---------------------------------
[...]此外,4.1[conv.lval]第1段指出,将lvalue-to-rvalue转换应用于“未初始化的对象”会导致未定义的行为;这应该用一个不确定值的对象来重新措辞。
特别是,第4.1段的拟议措词是:
当在未计算的操作数或其子表达式中发生LVALUE到RVALUE转换时(子句5[expr]),将不访问引用对象中包含的值。在所有其他情况下,转换的结果根据以下规则确定:
-否则,如果T是(可能是CV限定的)无符号字符类型(3.9.1[basic.basitic]),并且glvalue引用的对象包含一个不确定值(5.3.4[expr.new]、8.5[dcl.init]、12.6.2[class.base.init]),并且该对象没有自动存储持续时间,或者glvalue是一元&运算符的操作数,或者它绑定到引用,则结果是一个未指定的值。[脚注:每次对对象应用LVALUE到RVALUE转换时,值可能不同。分配给寄存器的值不确定的无符号char对象可能会陷阱。-结束脚注]
-否则,如果glvalue引用的对象包含不确定值,则行为未定义。
-否则,如果glvalue具有(可能是CV限定的)类型STD::NULLPTR_T,则prvalue结果为空指针常量(4.10[conv.ptr])。否则,glvalue指示的对象中包含的值是prvalue结果。
我正在使用mockito作为junit。在创建对象的模拟时,我有疑问。我有一个名为DBConnect的类。我需要数据库属性,如dbname、凭据等。PatientDetails使用这个类。现在,当我为PatientDetails编写junit时。所以我使用以下代码。 用这个我不能得到正确的结果。
我将firebase添加到我的android项目中,以使用firebase云消息传递。我按照文档进行了操作,但没有找到调用的任何说明。 我的应用程序工作很好,除了有一次它崩溃了以下错误。 当我搜索错误时,给出的解决方案是在启动时调用。 我想知道这是否真的有必要,因为文档没有提到它,我的应用程序在没有它的情况下工作(大部分)很好。 有人知道调用是否真的有必要,还有什么可能导致我上面提到的错误吗? 下
问题内容: 我们的团队正在使用SecureRandom生成密钥对列表(将SecureRandom传递给KeyPairGenerator)。对于以下两种选择中的哪一种,我们无法达成共识: 每次需要生成密钥对时都创建一个新实例 初始化静态实例并将其用于所有密钥对 通常哪种方法更好, 为什么 ? 添加:我的直觉是第二种选择更安全。但我唯一的论点是基于以下假设的理论攻击:假随机性是从当前时间戳派生的:某人
问题内容: 我需要转义[在SQL Server的sql查询中 实际上,我实际上是在寻找[[,但我不希望它像通配符一样起作用。我试过了 : 但是从这里得到错误信息: 消息102,级别15,状态1,行1“某物”附近的语法不正确。消息105,级别15,状态1,行1字符串’后的右引号; 问题答案: 使用: 您也可以使用: 在MSDN上的LIKE(Transact-SQL)中描述。
我有这样的代码: 当我们没有任何其他getInstance的静态方法时,是否初始化了此单例惰性?据我所知,类只在某些情况下初始化,比如: 类的实例是使用new()关键字或使用类的反射创建的。forName(),它可能在Java中引发ClassNotFoundException (Surce:http://javarevisited.blogspot.com/2012/07/when-class-l
我仍然被那些为了支持移动和转发而发明的规则弄糊涂了。有一件事我还不太确定: 转发引用是否只是rvalue引用(应用了引用折叠规则)? 如果它是一个rvalue引用,那么为什么函数: 不仅接受rvalues,还接受lvalues?