gpt4 book ai didi

c - 用 %p 打印空指针是未定义的行为?

转载 作者:太空狗 更新时间:2023-10-29 16:14:58 27 4
gpt4 key购买 nike

使用%p 转换说明符打印空指针是未定义的行为吗?

#include <stdio.h>

int main(void) {
void *p = NULL;

printf("%p", p);

return 0;
}

这个问题适用于 C 标准,而不适用于 C 实现。

最佳答案

这是我们受制于英语语言限制和标准结构不一致的那些奇怪的极端情况之一。所以充其量,我可以提出令人信服的反驳,因为不可能证明:)1


问题中的代码表现出明确定义的行为。

[7.1.4] 是问题的基础,让我们从这里开始:

Each of the following statements applies unless explicitly stated otherwise in the detailed descriptions that follow: If an argument to a function has an invalid value (such as a value outside the domain of the function, or a pointer outside the address space of the program, or a null pointer, [... other examples ...]) [...] the behavior is undefined. [... other statements ...]

这是笨拙的语言。一种解释是列表中的项目是所有库函数的 UB,除非被个别描述覆盖。但该列表以“例如”开头,表明它是说明性的,而不是详尽无遗的。例如,它没有提到字符串的正确空终止(对于例如 strcpy 的行为至关重要)。

因此很明显 7.1.4 的意图/范围只是“无效值”导致 UB(除非另有说明)。我们必须查看每个函数的描述以确定什么算作“无效值”。

示例 1 - strcpy

[7.21.2.3] 只说了这一点:

The strcpy function copies the string pointed to by s2 (including the terminating null character) into the array pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined.

它没有明确提到空指针,但也没有提到空终止符。相反,从“s2 指向的字符串”推断出唯一有效的值是字符串(即指向以 null 结尾的字符数组的指针)。

确实,这种模式可以在各个描述中看到。其他一些例子:

  • [7.6.4.1 (fenv)] store the current floating-point environment in the object pointed to by envp

  • [7.12.6.4 (frexp)] store the integer in the int object pointed to by exp

  • [7.19.5.1 (fclose)] the stream pointed to by stream

示例 2 - printf

[7.19.6.1]%p 说:

p - The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.

Null 是一个有效的指针值,本节没有明确提到 null 是一种特殊情况,也没有提到指针必须指向一个对象。因此它是定义的行为。


<子>1。除非标准作者挺身而出,或者除非我们能找到类似于 rationale 的东西澄清事情的文件。

关于c - 用 %p 打印空指针是未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44996471/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com