N1570规定这是未定义的行为:
§J.2/1 在使用具有自动存储期限的对象时,其值是不确定的(6.2.4、6.7.9、6.8)。
在这种情况下,我们的指针具有不确定的值:
§6.7.9/10 如果未显式初始化具有自动存储期限的对象,则其值是不确定的。如果未显式初始化具有静态或线程存储期限的对象,则:
— 如果它具有指针类型,则将其初始化为null指针;
然后我假设以下测试程序会出现未定义的行为:
#include <stdio.h>
int main(void) {
char * ptr;
printf("%p", (void*)&ptr);
}
我的关注点是函数
strtol
。首先,让我引用与参数 endptr
相关的 N1570 的部分:
这意味着必须将§7.22.1.4/5 如果主体序列具有预期的形式且基数值为零,则以第一个数字开头的字符序列根据 6.4.4.1 的规则解释为整数常量。[...] 如果
endptr
不是空指针,则将对最终字符串的指针存储在所指向的对象中。§7.22.1.4/7 如果主体序列为空或不具有预期的形式,则不执行转换;如果
endptr
不是空指针,则将nptr
的值存储在所指向的对象中。
endptr
指向一个对象,并且也需要在某个时刻对 endptr
进行解引用。例如,此实现 就这样做了。if (endptr != 0)
*endptr = (char *)(any ? s - 1 : nptr);
然而,这个高赞答案以及这个手册页面都显示未初始化的endptr
被传递给了strtol
。是否有例外情况使得这不是未定义行为?