本來是在 clang 編譯,想說試一下 g++ 是否有支援右值參考,編譯是會過,沒有任何警告或錯誤訊息
不過執行結果卻是大問題 @_____@||
測試碼如下:
#include <iostream>
int&& func(int&& x) {
x *= 7;
std::cout << x << " [&x: " << &x << "]\n";
return std::move(x);
// or
//return static_cast<int&&>(x);
}
void func2(int&& y) {
std::cout << y << " [&y: " << &y << "]\n";
}
int main() {
int ival = 3;
int *pival = &ival;
int&& rival = func(ival+0);
//int&& rival = func(std::move(ival));
rival++;
std::cout << ival << " [&ival: " << &ival << "]\n";
std::cout << *pival << " [pival: " << pival << "]\n";
std::cout << rival << " [&rival: " << &rival << "]\n";
func2(func(5));
std::cout << rival << " [&rival: " << &rival << "]\n";
int&& rival2 = func(6);
std::cout << rival << " [&rival: " << &rival << "]\n";
std::cout << rival2 << " [&rival2: " << &rival2 << "]\n";
int&& rival3 = func(7);
std::cout << rival << " [&rival: " << &rival << "]\n";
std::cout << rival2 << " [&rival2: " << &rival2 << "]\n";
std::cout << rival3 << " [&rival3: " << &rival3 << "]\n";
return 0;
}
先是 clang 的結果
$ clang++ -v
Ubuntu clang version 3.5.0-4ubuntu2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Target: x86_64-pc-linux-gnu
$ clang++ -O3 -std=c++11 ex015.cc -o ex015
$ ./ex015
21 [&x: 0x7ffc5b136540]
3 [&ival: 0x7ffc5b136544]
3 [pival: 0x7ffc5b136544]
22 [&rival: 0x7ffc5b136540]
35 [&x: 0x7ffc5b13653c]
35 [&y: 0x7ffc5b13653c]
22 [&rival: 0x7ffc5b136540]
42 [&x: 0x7ffc5b136538]
22 [&rival: 0x7ffc5b136540]
42 [&rival2: 0x7ffc5b136538]
49 [&x: 0x7ffc5b136534]
22 [&rival: 0x7ffc5b136540]
42 [&rival2: 0x7ffc5b136538]
49 [&rival3: 0x7ffc5b136534]
執行結果跟預期的一樣,右值參考功能有正常工作
改用 g++ 編譯也 OK(與 clang 同一系統環境)
只是執行結果就.....
$ g++ -v
Target: x86_64-linux-gnu
gcc version 4.9.1 (Ubuntu 4.9.1-16ubuntu6)
$ g++ -O3 -std=c++11 ex015.cc -o ex015
$ ./ex015
21 [&x: 0x7ffce55d8ac4]
3 [&ival: 0x7ffce55d8ac0]
3 [pival: 0x7ffce55d8ac0]
22 [&rival: 0x7ffce55d8ac4]
35 [&x: 0x7ffce55d8ac4]
35 [&y: 0x7ffce55d8ac4]
35 [&rival: 0x7ffce55d8ac4]
42 [&x: 0x7ffce55d8ac4]
42 [&rival: 0x7ffce55d8ac4]
42 [&rival2: 0x7ffce55d8ac4]
49 [&x: 0x7ffce55d8ac4]
49 [&rival: 0x7ffce55d8ac4]
49 [&rival2: 0x7ffce55d8ac4]
49 [&rival3: 0x7ffce55d8ac4]
每次呼叫 func(),x 都會使用相同位址,所以 rival 的值一直都跟著改變
而且正常來說,每次呼叫 func() 時都應該是『配置』新的位置存放 x 值,
rival 與 rival2 指向的位址也就應該要不同
正好手邊有 vc++ 2012 express,順便也測試了一下(code 一樣)
21 [&x: 003AFDDC]
3 [&ival: 003AFDE8]
3 [pival: 003AFDE8]
22 [&rival: 003AFDDC]
35 [&x: 003AFDE0]
35 [&y: 003AFDE0]
22 [&rival: 003AFDDC]
42 [&x: 003AFDE0]
22 [&rival: 003AFDDC]
42 [&rival2: 003AFDE0]
49 [&x: 003AFDE4]
22 [&rival: 003AFDDC]
42 [&rival2: 003AFDE0]
49 [&rival3: 003AFDE4]
請按任意鍵繼續 . . .
執行結果跟 clang 差不多,只差在傳回值最後如果未被參考(func2那裡)
則該位址會被重覆使用,雖然有些微差異,但並不影響執行結果