5

我想知道,使用 NULL 文件名调用 fopen 是否合法。如果是,它为我节省了 2 行代码。在我的 GNU/Linux 机器上它可以工作,但它必须是可移植的。我查看了 POSIX fopen,但它没有说明这个案例。它是未定义的行为吗?

4

3 回答 3

6

从 C 标准(从 1999 年开始):

7.1.4 库函数的使用

第 1 条:

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, or a
pointer to non-modifiable storage when the corresponding parameter is not
const-qualified) or a type (after promotion) not expected by a function with
variable number of arguments, the behavior is undefined.

同一标准中的描述fopen()没有提及NULL或根本没有提及null pointer

因此,根据 C 标准,NULL作为文件名字符串指针传递给fopen()会导致未定义的行为。

但是,POSIX 可能会扩展该行为。

于 2012-09-27T12:18:04.740 回答
0

POSIX 似乎对这种情况有明确的含义

[ENOENT]
文件名的组成部分未命名现有文件或文件名是空字符串。

因此您可以返回指向(静态)""的指针而不是空指针。

于 2012-09-27T11:55:11.797 回答
0

正如Alexey 指出的那样,当 NULL 参数的行为未指定时,这几乎肯定意味着该行为未定义。但我想补充一点,因为有正当的理由你想干净地把它卷成一个表达式。

你可以写一个函数:

FILE *
fopen_safe(char const *fname, char const *mode)
{
    if(fname == NULL)
        return NULL;

    return fopen(fname, mode);
}

或宏,如果您想避免函数调用的开销:

#define fopen_safe(fname, mode) \
    ( ((fname) == NULL) ? (NULL) : (fopen((fname), (mode))) )
于 2021-07-24T20:10:56.630 回答