C++右值引用行为(具体示例)

And*_*ker 2 c++ rvalue-reference c++11

我目前正在尝试使用libc ++来编译和运行MSVC.在这样做的过程中,我遇到了一个令人讨厌的错误(至少我认为是一个错误),这已经花了我一段时间来确定.我有以下repro代码:

int globalInt = 666;

class mini_move_iterator
{
public:

    mini_move_iterator(int* i) : __i(i){}

    int&& operator*() const
    {
        return static_cast<int&&>(*__i);
    }

    int* __i;
};

void foo(int&& rval)
{
    // Smash stack
    char stackUser[1000];
    for (int i = 0; i < 1000; ++i)
        stackUser[i] = 0xff;

    rval += 1;
}

int main()
{
    mini_move_iterator mmi(&globalInt);
    foo(*mmi);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我有几个问题:

1)这是合法的,即我是否避免陷入未定义行为的领域(它在语法上是合法的)?

2)foo返回后全局变量globalInt的期望值是多少(未定义可能是可接受的答案)?

编辑:

我应该已经明确表示这在VS与MSVC 12中不起作用.在foo中,变量rval指向堆栈上的临时变量,因此全局变量永远不会递增.

临时是在int && operator*()const中创建的.如果我更换:

return static_cast<int&&>(*__i);
Run Code Online (Sandbox Code Playgroud)

return std::move(*i);
Run Code Online (Sandbox Code Playgroud)

那一切都很好.使用C-cast也会导致临时创建.

T.C*_*.C. 8

1)这是合法的,即我是否避免陷入未定义行为的领域(它在语法上是合法的)?

你是如此,如此接近.__i是保留标识符,0xffto 的转换char很可能是实现定义的.除此之外,此代码有效且行为定义明确.

2)globalIntfoo返回后全局变量的期望值是什么(未定义可能是可接受的答案)?

667.返回的引用static_cast<int&&>(*__i)直接绑定到*__i- 即globalInt.不应该创建临时.[expr.static.cast]/p3中的适用规则自C++ 11以来基本保持不变,因此您肯定会看到编译器错误.

根据http://webcompiler.cloudapp.net/上的测试,在下一版本的VC++中修复了这个bug .