這個問題在這里已經有了答案: 這是 gcc/clang 過去一指標比較行為符合還是不標準? (2 個回答) 5 天前關閉。
如果一個陣列超過另一個陣列的末尾,則此代碼通過指標寫入一個值。
#include <stdio.h>
#include <inttypes.h>
extern int first[], second[];
#define ADDR_AFTER(ptr) ((uintptr_t)((ptr) 1))
int test(int *an_int) {
*second = 1;
if (ADDR_AFTER(first) == (uintptr_t)an_int) {
// ubsan does not like this.
*an_int = 2;
}
return *second;
}
int first[1] = {0}, second[1] = {0};
int main() {
if (ADDR_AFTER(first) == (uintptr_t)second) {
printf("test: %d\n", test(second));
printf("x: %d y: %d\n", *first, *second);
}
}
在任何時候我都不會直接比較兩個指向不同物件的指標(因為我將它們轉換為uintptr_t第一個)。我創建了一個指向陣列末尾的指標(這是合法的),但我從未取消參考該指標。據我所知,這應該不列印任何內容,或者列印:
測驗:2 x:0 y:2
當優化為-O1或更低時,它會列印在 Clang 上。-O2然而,在,它列印:
test: 1 x: 0 y: 2
With -O2 -fsanitize=undefined it prints the this to stdout:
test: 2 x: 0 y: 2
and the following to stderr:
runtime error: store to address 0x000000cd9efc with insufficient space for an object of type 'int' 0x000000cd9efc: note: pointer points here 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
with a reference to the assignment to an_int in test. Is this actually undefined behavior, or is this a bug in Clang?
uj5u.com熱心網友回復:
您的代碼沒有任何無效之處,編譯器是錯誤的。如果洗掉不必要的 ADDR_AFTER check in test(),代碼會按預期運行,不會出現 UBSan 錯誤。如果您在啟用優化且沒有 UBSan 的情況下運行它,您會得到錯誤的輸出(test=1,應該是 2)。
ADDR_AFTER(first) == (uintptr_t)an_int內部代碼的某些內容test()使 Clang 在使用-O2.
我測驗過,Apple clang version 11.0.3 (clang-1103.0.32.62)但看起來 Clang 13 和當前主干也有錯誤:https : //godbolt.org/z/s83ncTsbf - 如果您將編譯器更改為 GCC 的任何版本,您會看到它可以從main(),而 Clang 總是回傳 1 ( mov eax, 1)。
您可能應該為此提交 Clang 錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/360388.html
