私はいくつかのコードのバグを修正していましたが、コンパイラは関数dynscat()
が宣言されていないことを(合法的に)警告しました-受け入れ可能なコーディング標準についての誰かの考え-それで私は関数が定義されている場所(十分に簡単)とそれを宣言したヘッダー(なし)を追跡しました; Grrr!)。extern
しかし、私は構造体定義の詳細が次の宣言に必要であることに気付くと期待していましたqqparse_val
。
extern struct t_dynstr qqparse_val;
extern void dynscat(struct t_dynstr *s, char *p);
extern void qqcat(char *s);
void qqcat(char *s)
{
dynscat(&qqparse_val, s);
if (*s == ',')
dynscat(&qqparse_val, "$");
}
元のコードのqqcat()
関数は静的でした。extern宣言は、このコードスニペットに対するコンパイラの警告を鎮めます。dynscat()
関数宣言が完全に欠落していました。繰り返しますが、それを追加すると警告が鎮められます。
示されているコードフラグメントを使用すると、変数のアドレスのみが使用されていることは明らかです。したがって、構造の詳細が不明であっても問題がないことは、あるレベルでは理にかなっています。変数の場合extern struct t_dynstr *p_parseval;
、この質問は表示されません。それは100%期待されます。コードが構造体の内部にアクセスする必要がある場合は、構造体の定義が必要になります。しかし、変数が(構造体へのポインターではなく)構造体であると宣言した場合、コンパイラーは構造体のサイズを知りたいと常に思っていましたが、明らかにそうではありません。
私はGCCに文句を言うように仕向けようとしましたが、GCC4.7.1でさえもそうではありません。
gcc-4.7.1 -c -Wall -Wextra -std=c89 -pedantic surprise.c
このコードは、AIX、HP-UX、Solaris、Linuxで10年間コンパイルされているため、GCC固有ではありません。
質問
これはC標準で許可されていますか(主にC99またはC11ですが、C89でも許可されます)?どのセクション?それとも、移植されたすべてのマシンで動作するが、標準によって正式に認可されていない奇妙なケースにぶつかっただけですか?