获取未初始化指针的地址是未定义的行为吗?

5 c pointers undefined-behavior language-lawyer

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);
}
Run Code Online (Sandbox Code Playgroud)

我的动机是关注strtol功能.首先,让我引用与endptr参数相关的N1570部分:

§7.22.1.4/ 5如果主题序列具有预期形式且base的值为零,则根据6.4.4.1的规则将以第一个数字开头的字符序列解释为整数常量.[...]指向最终字符串的指针存储在指向的对象中endptr,前提endptr是该指针不是空指针.

§7.22.1.4/ 7如果主题序列为空或没有预期的形式,则不进行转换; 如果不是空指针,则值nptr存储在指向的对象中.endptrendptr

这意味着endptr需要指向一个对象,并且endptr在某些时候也需要解除引用.例如,此实现是这样做的:

if (endptr != 0)
    *endptr = (char *)(any ? s - 1 : nptr);
Run Code Online (Sandbox Code Playgroud)

然而,这个高度赞成的答案以及这个手册页都显示endptr被传递给strtol未初始化的.是否有一个例外,这使得这不是未定义的行为?

unw*_*ind 9

指针的值和地址不一样.

void *foo;
Run Code Online (Sandbox Code Playgroud)

该指针具有未定义的值,但必须很好地确定地址(foo即值)&foo(否则我们无法访问它).

至少这是我的直觉理解,我现在没有挖掘标准,我只是认为你误读了它.

在谈论代码时,两者有时会混淆("指针的地址是什么?" 可能意味着"指针的值是什么,它指向的是什么地址?")但它们确实是截然不同的.


oua*_*uah 4

在这个表达式中:

&ptr

操作数的地址&,即对象的地址ptr被产生,但ptr对象从未被评估。

(C11, 6.3.2.1p2) “除非它是 sizeof 运算符、一元 & 运算符、++ 运算符、-- 运算符、. 运算符的左操作数或赋值运算符的操作数,否则左值不具有数组类型的值被转换为存储在指定对象中的值(并且不再是左值);这称为左值转换。”