2017-05-19 12 views
4

のIAR Embedded Cコンパイラはこれに満足している、と私はそれが正しいCのコードだったと仮定:Cでは、不完全な型の配列へのポインタを使用する必要がありますか?

struct incomplete; 
typedef struct incomplete (*why_not)[2]; 
struct incomplete {struct incomplete *known_to_work;} array[2]; 
why_not ok = &array; 

しかし、why_notの定義上のgccと打ち鳴らすチョーク:

incomplete.c:2:29: error: array type has incomplete element type ‘struct incomplete’ 
typedef struct incomplete (*why_not)[2]; 
          ^

技術的には、そこを"不完全な配列の型へのポインタ"の定義を拒否する理由はありません。結局のところ、構造定義は、そのような変数が逆参照される場合、またはポインタ演算が実行される場合にのみ必要とされます。

可能であれば、構造定義を非表示にしたいと思っています。

Cの標準はこれについて何を言いますか?

+0

どのような状況(関数パラメータさえも)でタイプ "不完全型の配列"を使用することはできません –

+0

@ M.M実際には、どうしてですか? –

+0

IARにバグレポートを提出してください。これが私のコンパイラを使わない理由です。彼らは、遵守していないバグの修正を受けるためにお金を払うことを求める胃があります。これは、Cのこの部分が1980年代以来存在していたため、余計に恥ずかしいことです。 – Lundin

答えて

6

コードでは、エレメントタイプが不完全な配列宣言子が使用されています。このISO Cにおける制約違反、6.7.6.2/1 アレイは宣言子に従って:オプションタイプ修飾子とキーワード静的に加え

制約

[]を区切ることができます式または*です。式の区切り(配列のサイズを指定する)の場合、式は整数型でなければなりません。式が定数式である場合、それは0より大きい値を持たなければならない。要素の型は、不完全または関数型であってはならない。

5

次の文

typedef struct incomplete (*why_not)[2]; 

は、二つstruct incompleteの配列へのポインタです。まだ定義されていないので、コンパイラはstruct incompleteのサイズをまだ知りません。

以下は、しかし、動作します:

typedef struct incomplete *why_not[2]; 

をすなわち:struct incompleteへのポインタの配列。コンパイラは、不完全な型へのポインタのサイズを知っている(つまり、アドレスを格納するのに必要なサイズだけである)。


編集:両方の宣言はただのポインタを宣言しているので、

コンパイラは、(限り何のポインタ演算が行われていないとして)のいずれかの場合にはstruct incompleteの大きさを知る必要はありません。

+2

コンパイラは配列のポインタのサイズを知っています不完全な型もあります。これは単なるアドレスです。私が指摘したように、これを受け入れるコンパイラは少なくとも1つあります。問題は、標準(C99またはC11)は何を言いますか? –

+0

@あなたは正しいです。 –

+0

異なる型付きオブジェクトのアドレスは、サイズが異なるかもしれません(例えば 'int *'は2バイト、 'void *'は3バイトです)。 –

関連する問題