簡體   English   中英

條件運算符中的未定義行為

[英]undefined behavior in conditional operator

我不得不分享這個:

在涉及條件運算符的以下微不足道的錯誤中,我被掛了2天。

這是一個簡單的修正,但我想知道:

  1. 為什么錯誤的代碼編譯?
  2. 這個bug在做什么?
  3. 為什么這么難以追蹤?

越野車代碼:

 std::map<int, some_class>   my_map;
int key_ctr = 0;
 //...
std::map<int, some_class>::iterator it_next   =  
                                            key_ctr == 0  ?
                                 it_next  =  my_map.begin()      // BUG!!!
                                 :
                                 it_next  =  --my_map.end();     // BUG!!!!

  // .....

顯然,我錯誤地編寫了條件運算符。 當我最終發現並糾正這個錯誤時,Eveyrthing工作完全正常:

正確代碼:

 std::map<int, some_class>   my_map;
int key_ctr = 0;
 //...
std::map<int, some_class>::iterator it_next   =  
                                            key_ctr == 0  ?
                                 my_map.begin()              // CORRECTED!
                                 :
                                 --my_map.end();             // CORRECTED!

當我的程序靠近有缺陷的部分時,我的程序就懸掛了 - 好像它處於一個無限循環中。 當我用valgrind運行時,我得到了類似的東西

....
==24570== Warning: set address range perms: large range [0x1a7731000, 0x1c5f79000) (defined)
==24570== Warning: set address range perms: large range [0x1c5f79000, 0x1e47c1000) (defined)
==24570== Warning: set address range perms: large range [0x1e47c1000, 0x203009000) (defined)
==24570== Warning: set address range perms: large range [0x203009000, 0x221851000) (defined)
.....
==3733== More than 10000000 total errors detected.  I'm not reporting any more.

這完全沒有用,並指出我在錯誤的導演(我以為我在堆上分配太多,不知何故)。

再次,

  1. 為什么錯誤的代碼編譯?
  2. 這個bug在做什么?
  3. 為什么這么難以追蹤?

謝謝孩子們。

1)編譯器只檢查語法和格式良好的程序。 由您來發現邏輯錯誤。

2)這是未定義的行為。 這就是為什么:


whatever_non_POD_type it_next = condition ? it_next = whatever1 : 
                                            it_next  = whatever2; 

實際上,您可以將其縮小到:

It it_next = it_next = whatever;

什么都不重要。 重要的是,在完整語句執行( ;到達)之前, it_next 是未初始化的 那是什么的

It it_next = ...

部分嘗試做。 首先,它試圖評估右側的內容。 這是it_next = whatever 哪個叫it_next.operator = (whatever) 所以你在一個未初始化的對象上調用一個成員函數 哪個是未定義的行為。 當當!

3)所有未定義的行為很難追蹤。 這就是為什么你至少應該意識到常見的情況。

3為什么這么難以追蹤?

因為您沒有打開編譯器警告?

$ g++ -std=c++0x -pedantic -Wall -Werror -g    m.cc   -o m
cc1plus: warnings being treated as errors
m.cc:10: error: operation on ‘it_next’ may be undefined
m.cc: In function ‘void __static_initialization_and_destruction_0(int, int)’:
m.cc:6: error: operation on ‘it_next’ may be undefined
make: *** [m] Error 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM