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()同規格での説明は、言及されていないNULLnull pointer、まったくありません。

そのため、C 標準に従って、NULLファイル名文字列ポインターとして渡すとfopen()、未定義の動作が発生します。

ただし、POSIX は動作を拡張する場合があります。

于 2012-09-27T12:18:04.740 に答える
0

POSIXは、この場合に定義された意味を持っているようです

[ENOENT]
filename のコンポーネントが既存のファイルを指定していないか、filename が空の文字列です。

""したがって、null ポインターの代わりに(静的) へのポインターを返すことができます。

于 2012-09-27T11:55:11.797 に答える
0

Alexey が指摘しているように、NULL 引数の動作が指定されていない場合、それはほぼ確実に動作が未定義であることを意味します。しかし、それを 1 つの式にきれいにまとめたい正当な理由があるので、これに追加したいと思います。

関数を書くことができます:

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 に答える