用%p打印空指针是未定义的行为吗? [英] Printing null pointers with %p is undefined behavior?

查看:664
本文介绍了用%p打印空指针是未定义的行为吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it undefined behavior to print null pointers with the %p conversion specifier?

#include <stdio.h>

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

    printf("%p", p);

    return 0;
}

该问题适用于C标准,不适用于C实现.

The question applies to the C standard, and not to C implementations.

推荐答案

这是一些奇怪的案例,其中我们受到英语语言的限制以及标准中结构不一致的限制.因此充其量,我可以提出一个令人反感的论点,因为不可能证明:) 1

问题中的代码表现出明确的行为.

The code in the question exhibits well-defined behaviour.

由于 [7.1.4] 是问题的基础,所以从这里开始:

As [7.1.4] is the basis of the question, let's start there:

以下语句中的每一个均适用,除非在以下详细说明中另有明确说明:函数的自变量具有无效值(例如,例如在函数域之外的值,或者程序地址空间外部的指针,或空指针 [...其他示例...] ) [...] 行为未定义. [...其他声明...]

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的行为至关重要).

This is clumsy language. One interpretation is that the items in the list are UB for all library functions, unless overridden by the individual descriptions. But the list starts with "such as", indicating that it's illustrative, not exhaustive. For example, it does not mention correct null-termination of strings (critical for the behaviour of e.g. strcpy).

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

Thus it's clear the intent/scope of 7.1.4 is simply that an "invalid value" leads to UB (unless stated otherwise). We have to look to each function's description to determine what counts as an "invalid value".

[7.21.2.3] 仅说:

strcpy函数将s2指向的字符串(包括终止的空字符)复制到s1指向的数组中.如果在重叠的对象之间进行复制,则行为是不确定的.

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终止的字符数组的指针).

It makes no explicit mention of null pointers, yet it makes no mention of null terminators either. Instead, one infers from "string pointed to by s2" that the only valid values are strings (i.e. pointers to null-terminated character arrays).

实际上,可以在各个描述中看到这种模式.其他示例:

Indeed, this pattern can be seen throughout the individual descriptions. Some other examples:

[7.6.4.1(fenv)] 将当前浮点环境存储​​在envp

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

  • [7.12.6.4(frexp)] 将整数存储在exp

  • [7.19.5.1(关闭)] stream

  • [7.19.6.1] 谈到%p:

    p-参数应为指向void的指针.指针的值以实现定义的方式转换为一系列打印字符.

    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是一种特殊情况,也没有指出指针必须指向一个对象.这样就定义了行为.

    Null is a valid pointer value, and this section makes no explicit mention that null is a special case, nor that the pointer has to point at an object. Thus it is defined behaviour.

    1.除非标准作者挺身而出,或者除非我们可以找到类似于

    1. Unless a standards author comes forward, or unless we can find something similar to a rationale document that clarifies things.

    这篇关于用%p打印空指针是未定义的行为吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆