获取临时对象的地址
§5.3.1 一元运算符,第 3 节
一元 & 的结果运算符是指向其操作数的指针。 操作数应为左值或限定 ID。
在这种情况下,“应该”到底意味着什么?这是否意味着获取临时地址是错误的?我只是想知道,因为 g++ 只给我一个警告,而 comeau 拒绝编译以下程序:
#include <string>
int main()
{
&std::string("test");
}
g++ 警告:获取临时地址
comeau 错误: 表达式必须是左值或函数指示符
请问有人有 Microsoft 编译器或其他编译器并且可以测试这个程序吗?
§5.3.1 Unary operators, Section 3
The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id.
What exactly does "shall be" mean in this context? Does it mean it's an error to take the address of a temporary? I was just wondering, because g++ only gives me a warning, whereas comeau refuses to compile the following program:
#include <string>
int main()
{
&std::string("test");
}
g++ warning: taking address of temporary
comeau error: expression must be an lvalue or a function designator
Does anyone have a Microsoft compiler or other compilers and can test this program, please?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
标准语言中的“应”一词意味着严格要求。所以,是的,您的代码格式不正确(这是一个错误),因为它尝试将地址运算符应用于非左值。
然而,这里的问题不是尝试获取临时地址。问题再次出现在获取非左值的地址。临时对象可以是左值或非左值,具体取决于生成该临时对象或提供对该临时对象的访问的表达式。在您的情况下,您有
std::string("test")
- 函数样式转换为非引用类型,根据定义它会生成非左值。因此出现了错误。如果您希望获取临时对象的地址,您可以通过这样做来解决限制,例如
,只要临时对象存在,结果指针就保持有效。还有其他方法可以合法地获取临时对象的地址。只是你的具体方法恰好是非法的。
The word "shall" in the standard language means a strict requirement. So, yes, your code is ill-formed (it is an error) because it attempts to apply address-of operator to a non-lvalue.
However, the problem here is not an attempt of taking address of a temporary. The problem is, again, taking address of a non-lvalue. Temporary object can be lvalue or non-lvalue depending on the expression that produces that temporary or provides access to that temporary. In your case you have
std::string("test")
- a functional style cast to a non-reference type, which by definition produces a non-lvalue. Hence the error.If you wished to take address of a temporary object, you could have worked around the restriction by doing this, for example
whith the resultant pointer remaining valid as long as the temporary exists. There are other ways to legally obtain address of a temporary object. It is just that your specific method happens to be illegal.
当 C++ 标准中使用“shall”这个词时,它的意思是“必须否则处以死刑”——如果一个实现不遵守这一点,那么它就是错误的。
When the word "shall" is used in the C++ Standard, it means "must on pain of death" - if an implementation does not obey this, it is faulty.
MSVC 中允许使用已弃用的 /Ze(启用扩展)选项。在 MSVC 的早期版本中是允许的。它会生成启用所有警告的诊断:
除非使用 /Za 选项(强制 ANSI 兼容性),否则:
It is permitted in MSVC with the deprecated /Ze (extensions enabled) option. It was allowed in previous versions of MSVC. It generates a diagnostic with all warnings enabled:
Unless the /Za option is used (enforce ANSI compatibility), then:
&std::string("test");
正在询问函数调用的返回值的地址(我们将忽略这个函数是一个 ctor 的事实,因为这是无关紧要的)。在您将其分配给某物之前,它没有地址。因此这是一个错误。&std::string("test");
is asking for the address of the return value of the function call (we'll ignore as irrelevant the fact that this function is a ctor). It didn't have an address until you assign it to something. Hence it's an error.C++ 标准实际上是对一致的 C++ 实现的要求。在某些地方,它被编写为区分一致性实现必须接受的代码和一致性实现必须给出诊断的代码。
因此,在这种特殊情况下,如果获取了右值的地址,一致的编译器必须给出诊断。两个编译器都这样做,因此它们在这方面是一致的。
如果某个输入导致诊断,该标准并不禁止生成可执行文件,即警告是有效的诊断。
The C++ standard is a actually a requirement on conformant C++ implementations. At places it is written to distinguish between code that conformant implementations must accept and code for which conformant implementations must give a diagnostic.
So, in this particular case, a conformant compiler must give a diagnostic if the address of an rvalue is taken. Both compilers do, so they are conformant in this respect.
The standard does not forbid the generation of an executable if a certain input causes a diagnostic, i.e. warnings are valid diagnostics.
我不是标准专家,但这对我来说听起来确实是一个错误。 g++ 通常只对真正错误的事情发出警告。
I'm not a standards expert, but it certainly sounds like an error to me. g++ very often only gives a warning for things that are really errors.