以下のコードで「1506-221 (S) Initializer must be a valid constant expression」というエラーが表示されます。
FILE *fp[] = {stdout, dump_f};
これは受け入れられますか?これを達成する適切な方法は何ですか?
stdout
このエラーは、システム上で変数が実際#defined
には関数呼び出しに展開されるマクロであることを示唆しています。
実際、他の人が示唆しているように、stdout
コンパイル時に値がわからないため、静的初期化子で指定できない extern 宣言された変数である可能性があります。
どちらに関係なく、解決策は同じでなければなりません-私は次のようなことを試します:
FILE *fp[2];
void init_fp()
{
fp[0] = stdout;
fp[1] = dump_f;
}
可能性が高い、stdout
および/またはdump_f
マクロまたは(問題である可能性が高い)外部グローバルです。
私がこのコードを持っている場合:
// external.c
int hello = 1234;
// external.h
extern int hello;
// main.c
#include "external.h"
int world = hello; // error!
hello
の値が不明なため、示された行でエラーが発生します。
stdout
そして、次のように、グローバルdump_f
として宣言される可能性が最も高いです。extern
extern FILE *stdout, *stdin, *stderr, *dump_f;
それがグローバルの場合、C は関数呼び出しによる初期化をサポートしていません。関数stdout
呼び出し用のマクロ (最初に提案されたとおり) の場合、それを使用してグローバルを初期化することはできません。
古典的に、ほとんどの Unix システムは、有効な定数式に縮小された のstdout
ようなものとして定義していました。(&_iob[1])
たとえば、Solaris は今でもそうです。
数年前、現在、GNU C ライブラリは の定義をstdout
定数ではないものに変更したため、FILE *
変数を標準ファイル ポインターのいずれかに初期化するために使用されていた古いコードはコンパイルされなくなりました。これは C 標準で認められているため、文句を言うメリットはありません。静的ファイル ポインタを標準 I/O チャネルの 1 つに初期化し、再コーディングして問題を回避することはできないことを受け入れる必要があります。(しかし、それはまだ迷惑です。)