12
#include <stdio.h>

int main()
{
  printf("%d", sizeof(struct token *));
}

上記のコードは、Linux で gcc を使用してコンパイルおよびリンクできます。舞台裏のことを説明してくれる人はいますか?ポイントはメモリの固定サイズを取ることを知っているので、構造体トークンはsizeofとは無関係ですが、gccで警告オプションをオンにしても、「存在しない」構造体に関する警告はまったくありません。質問のコンテキストは、他の人がソースコードを読んでいるということです。「構造体トークン」の定義を見つけるのに非常に苦労していますが、もちろん失敗しました。

4

2 に答える 2

12

へのポインタのサイズを取得しようとしているためですstruct token。ポインタのサイズは、構造が実際にどのように定義されているかには依存しません。

一般に、型の変数を宣言することもできますがstruct token*、それを逆参照することはできません(たとえば、ポインターを介してメンバーにアクセスします)。

于 2012-05-25T08:29:19.813 に答える
9

C 標準を言い換えると、不完全な型とは、オブジェクトを記述しているが、そのサイズを決定するために必要な情報が不足している型です。

void は別の不完全な型です。他の不完全型とは異なり、void は完成できません。

この「不完全型」は、ハンドルの種類によく使用されます。ライブラリを使用すると、「ハンドル」を何かに割り当て、それを操作し、再び破棄できます。これはすべて、ライブラリにカプセル化されて発生します。ユーザーとしてのあなたは、内部で何が起こるかわかりません。

例:

lib.h:

struct data * d_generate(void);
void d_set(struct data *, int);
int d_get(struct data *);
void d_free(struct data*);

lib.c:

#include "lib.h"
#include <stdlib.h>
struct data { int value; };
struct data * d_generate(void) {
    return malloc(sizeof(struct data))
}
void d_set(struct data * d, int v) {
    d -> value = v;
}
int d_get(struct data * d) {
    return d->value;
}
void d_free(struct data* d) {
   free(d);
}

user.c:

#include "lib.h"
[...]
struct data * d = d_generate();
d_set(d, 42);
int v = d_get(d);
// but v = d->value; doesn't work here because of the incomplete definition.
d_free(d);
于 2012-05-25T08:33:34.180 に答える