作者 主題: g++ 4.9.1 右值參考有問題!!?  (閱讀 3608 次)

0 會員 與 1 訪客 正在閱讀本文。

Yamaka

  • 俺是博士!
  • *****
  • 文章數: 4913
    • 檢視個人資料
    • http://www.ecmagic.com
g++ 4.9.1 右值參考有問題!!?
« 於: 2015-05-20 16:38 »
本來是在 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那裡)
則該位址會被重覆使用,雖然有些微差異,但並不影響執行結果