33

§5.3.1 一元运算符,第 3 节

一元 & 运算符的结果是指向其操作数的指针。操作数应为左值或限定 ID。

在这种情况下,“应该”到底是什么意思?这是否意味着获取临时地址是错误的?我只是想知道,因为 g++ 只给了我一个警告,而 comeau 拒绝编译以下程序:

#include <string>

int main()
{
    &std::string("test");
}

g++警告taking address of temporary

喜剧错误expression must be an lvalue or a function designator

请问有人有微软编译器或其他编译器并且可以测试这个程序吗?

4

7 回答 7

34

标准语言中的“shall”一词意味着严格的要求。所以,是的,您的代码格式错误(这是一个错误),因为它试图将地址运算符应用于非左值。

但是,这里的问题不是尝试获取临时地址。问题再次是处理非左值。临时对象可以是左值或非左值,具体取决于产生该临时对象或提供对该临时对象的访问的表达式。在您的情况下,您有std::string("test")- 转换为非引用类型的功能样式,根据定义,它会产生非左值。因此错误。

如果您希望获取临时对象的地址,您可以通过这样做来解决限制,例如

const std::string &r = std::string("test");
&r; // this expression produces address of a temporary

只要临时存在,结果指针就保持有效。还有其他方法可以合法地获取临时对象的地址。只是你的具体方法恰好是非法的。

于 2010-02-17T15:29:21.360 回答
6

当 C++ 标准中使用“shall”这个词时,它的意思是“必须承受死亡的痛苦”——如果一个实现不遵守这一点,那就是错误的。

于 2010-02-17T12:56:11.240 回答
3

在 MSVC 中允许使用已弃用的 /Ze(启用扩展)选项。它在以前版本的 MSVC 中是允许的。它会生成启用所有警告的诊断:

警告 C4238:使用了非标准扩展:类右值用作左值。

除非使用 /Za 选项(强制 ANSI 兼容性),否则:

错误 C2102:“&”需要左值

于 2010-02-17T13:03:56.977 回答
1

&std::string("test");正在询问函数调用的返回值的地址(我们将忽略此函数是一个ctor这一事实无关紧要)。在您将其分配给某物之前,它没有地址。因此这是一个错误。

于 2010-02-17T13:05:03.567 回答
1

C++ 标准实际上是对符合 C++ 实现的要求。在某些地方,它被编写来区分符合实现必须接受的代码和符合实现必须给出诊断的代码。

因此,在这种特殊情况下,如果使用了右值的地址,则符合标准的编译器必须给出诊断。两个编译器都这样做,因此它们在这方面是一致的。

如果某个输入导致诊断,该标准不禁止生成可执行文件,即警告是有效的诊断。

于 2010-02-17T15:19:31.943 回答
0

我不是标准专家,但对我来说这听起来确实是个错误。g++ 通常只对真正的错误发出警告。

于 2010-02-17T12:58:07.043 回答
-2

用户定义的转换

struct String {
    std::string str;

    operator std::string*() {
        return &str;
    }
};

std::string *my_str = String{"abc"};
于 2019-08-18T20:01:06.587 回答