這是OS X下g++的bug嗎?

#include &
using namespace std;
int a[20];
int main(){
cout&<&<(a-1&

這是s.cpp的內容


a-1本身已經是未定義行為了

C++標準規定,對於數組,只有獲取數組的元素指針和尾元素後指針是合法的

也就是對於int a[10];a + i只在i &>= 0 i &<= 10時是合法的,a[i]只在i&>=0 i &< 10時是合法的

然後,C++標準沒有要求指針比較滿足全序關係


這個在C++標準的Relational operators裡面有講

指針間可以比較,但是有條件的,大致翻譯過來是幾種:

1 假如兩個指針類型相同又指向同個對象,則它們的&>=和&<=運算是true,&>和&<是false

2 假如兩個指針指向的對象是在一個類的對象中的不同欄位,而且欄位的訪問控制許可權是一樣(都是public,protected或private),則代碼中後定義的地址大,這時候比較運算也是有明確結果的

3 假如兩個指針指向的是同一個union對象的欄位,則它們相等(當然比較時自動轉為void *)

4 假如兩個指針指向的是同一個數組內部+數組末尾額外元素中的不同元素,則下標大的指針大,比如int a[10],則指針值為a[0]到a[10],都算是合法的,雖然a[10]的內容你不能訪問,但這個指針值是可以出現的,指向這11個元素的指針可以互相比較大小

另外,對於2和4有個遞歸定義,比如你一個對象裡面有兩個欄位都是public,一個是int類型,一個是char數組,則指向int欄位的指針也可以和指向char數組某合法元素(包括末尾額外的那個元素)的指針做比較

其餘情況,結果是unspecified,看編譯器心情

所以你寫a+1&>a,應該無論如何都是1,但是a-1&


這個有點意思,可以打出a的數值看一下(強制轉化成int),也許編譯器認為數組沒用到於是整個優化掉了,然後a變成了NULL,也就是0,然後a-1溢出了?


雖然有點跑題,但是你先看一下g++是不是clang++的軟連接。。。

另外指針比較是ub,不要依賴ub


比大小比的是值大小,不是比內存地址的大小


指針間的比較是未定義行為吧。。?貌似指針只能作差然後比較來著。。?


推薦閱讀:

遞歸下降的語法分析程序如何進行錯誤恢復?
模板編程如何引入類型是否存在條件???
能否通過對編譯器或者編譯環境的限制來應對木馬或者病毒呢?
如何構造上下文無關文法?
現代C++編譯器是否會根據debug期間運行所得的信息來進行優化?

TAG:程序員 | 代碼 | 編譯器 |