簡體   English   中英

獲取未初始化指針的地址是未定義的行為嗎?

[英]Is it undefined behavior to take the address of an uninitialized pointer?

N1570聲明這是未定義的行為:

§J.2/ 1具有自動存儲持續時間的對象的值在不確定時使用(6.2.4,6.7.9,6.8)。

在這種情況下,我們的指針具有不確定的值:

§6.7.9/ 10如果沒有明確初始化具有自動存儲持續時間的對象,則其值是不確定的。 如果未顯式初始化具有靜態或線程存儲持續時間的對象,則:

- 如果它有指針類型,則將其初始化為空指針;

然后,我假設以下測試程序顯示未定義的行為:

#include <stdio.h>

int main(void) {
    char * ptr;
    printf("%p", (void*)&ptr);
}

我的動機是strtol功能。 首先,讓我引用與endptr參數相關的endptr

§7.22.1.4/ 5如果主題序列具有預期形式且base的值為零,則根據6.4.4.1的規則將以第一個數字開頭的字符序列解釋為整數常量。 [...]指向最終字符串的指針存儲在endptr指向的對象中,前提是endptr不是空指針。

§7.22.1.4/ 7如果主題序列為空或者沒有預期的形式,則不進行轉換; 如果endptr不是空指針,則nptr的值存儲在endptr指向的對象中。

這意味着endptr需要指向一個對象,並且該endptr在某個時候被解除引用。 例如, 此實現是這樣做的

if (endptr != 0)
    *endptr = (char *)(any ? s - 1 : nptr);

然而, 這個高度贊成的答案以及這個手冊頁都顯示endptr被傳遞給strtol未初始化。 是否有一個例外,這使得這不是未定義的行為?

指針的值和地址不一樣。

void *foo;

該指針有一個未定義的值,但foo的地址,即&foo的值,必須很好地確定(因為否則我們無法訪問它)。

至少這是我的直覺理解,我現在沒有挖掘標准,我只是認為你誤讀了它。

在談論代碼時,兩者有時會混淆(“指針的地址是什么?” 可能意味着“指針的值是什么,它指向的是什么地址?”)但它們確實是截然不同的。

在這個表達式中:

&ptr

&操作數的地址,即ptr對象的地址被生成,但ptr對象永遠不會被計算。

(C11,6.3.2.1p2)“除非它是sizeof運算符,一元&運算符,++運算符, - 運算符或。運算符或賦值運算符的左操作數的操作數,否則它是左值沒有數組類型的數據被轉換為存儲在指定對象中的值(並且不再是左值);這稱為左值轉換。“

不,這不是未定義的行為。 只有ptr是未初始化的並且具有不確定的值,但是&ptr具有適當的值。

strtol上的標准報價是什么:

...如果主題序列為空或沒有預期的形式,則不執行轉換; 如果endptr不是空指針,則nptr的值存儲在endptr指向的對象中。

以上引用是關於這樣的調用的討論:

strtol(str, 0, 10);

手冊頁中的調用和鏈接的答案完全沒問題。

看這個例子

char * ptr; 

由於ptr沒有指向任何對象,因此解除引用它會調用未定義的行為。 但是當你將其地址傳遞給strtol ,有了語法

long int strtol(const char *nptr, char **endptr, int base);  

在聲明中

long parsed = strtol("11110111", &ptr, 2);   

strtolendptr參數指向對象ptr並且derefeencing它不會調用任何UB。

我只能訪問N1256,但如果有任何重大變化,我會感到驚訝。

最相關的部分是“6.5.3.2地址和間接操作符”

特別是第3段(我的重點):

語義

3 一元&運算符產生其操作數的地址。 如果操作數具有類型''type'',則結果具有類型''指向類型''的指針。 如果操作數是一元*運算符的結果,則不會對該運算符和&運算符進行求值,結果就好像兩者都被省略,除了對運算符的約束仍然適用且結果不是左值。 類似地,如果操作數是[]運算符的結果,則[]運算符和[]所暗示的一元*都不會被計算,結果就像刪除了&運算符並且[]運算符被更改為a +運算符。 否則,結果是指向由其操作數指定的對象或函數的指針。

正如許多人所指出的那樣,OP中引用的段落均未適用。 某物的價值及其地址是非常不同的。

我認為,允許(通過沒有禁令)對未提出的未初始化值的限制沒有任何限制。

注意:我們都知道這很好,但很難在這些標准中找到明確說“是的,你可以這樣做”的陳述。

暫無
暫無

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

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