33

私は初心者ではありません。次のイディオムに精通しています。

typedef struct Foo_ Foo;// I know typedef struct Foo Foo is fine, I'm just trying to make it clearer
struct Foo_
{
    int value;
    Foo *link;
};

宣言される前に名前(識別子)を使用することは許可されていないというのが私の理解であるため、私は突然混乱しました。しかし、宣言typedef struct Foo_ Fooでは、識別子Foo_はまだ存在していません!なぜコンパイラはこれが起こるのを許可するのですか?誰かがこれに光を当てて、この種の構文の正当性を私に説明してくれませんか?

ウィキペディアの引用:目的はtypedef、既存のタイプに代替名を割り当てることです。

---> 8---

たくさんの有益な情報をありがとうございました。

4

7 に答える 7

33

これはまったく問題ありません。あなたのようなタグの最初の使用はstruct、型の前方宣言ですstruct

_Fooの使用法が準拠していないことに注意してください。アンダースコアが先頭にあり、大文字が続く識別子は予約されています。そうしないでください。末尾のアンダースコアは問題ありません。

于 2012-11-29T13:00:16.553 に答える
14

これは 6.7.2.3p8 でカバーされています。

6.7.2.3 タグ

セマンティクス
[...]

8 -構造体または共用体の識別子の形式の型指定子が[構造体または共用体の定義] または [構造体または共用体の宣言] として以外に出現し、タグとしての識別子の他の宣言がない場合可視の場合、不完全な構造体または共用体型を宣言し、識別子をその型のタグとして宣言します。

の型指定子struct Footypedef struct Foo Foo、定義 ( struct Foo {...};) または宣言 ( struct Foo;) に含まれていないため、6.7.2.3p8 に該当します。

a について特別なことは何もないことに注意してくださいtypedef。たとえば、次のように書くこともできます

struct A { struct Foo *p; };

以前の定義または宣言を表示する必要はありません。

ただし、関数の宣言または定義では:

void foo(struct Foo *p);

struct Fooが事前に宣言されていない場合、宣言のスコープは関数の宣言または定義だけになり、後続の の宣言または定義と型互換性はありませんFoo

于 2012-11-29T13:06:51.367 に答える
4
ISO c99 : 6.2.1 Scopes of identifiers

7

構造体、共用体、および列挙タグには、タグを宣言する型指定子でタグが出現した直後から始まるスコープがあります。

typedef struct _Foo Foo; // You can do this because it's just the typedef the new type

struct _Foo *myfoo ; // It's pointer to struct _Foo (an incomplete type)
                      //but make sure before using myfoo->value   
                    // struct definition should be available

struct _Foo MyFoo;  // It's  definition of MyFoo but don't forget 
                    // to give the definition of struct _Foo (gcc extension). 

struct _Foo;  // forward declaration

struct _Foo    // It's the definition
{
    int value;
    Foo *link;
};

functionの実際の定義の前または前functionsに行うのと同じように、それを使用して行うこともできます。forward declarationtypedefstruct

void func(int );
typedef void (*func_t)(int);

void func(int x)
{
 //actual definition
}
于 2012-11-29T13:13:13.480 に答える
3

typedef型のエイリアスを作成するために使用されます。しかし、その型は typedef されたときに必ずしも存在するとは限りません。

例えば、

あなただけの場合:

struct Foo;

プログラムのどこにも定義しないと、struct Fooコンパイルされます。コンパイラは、それがどこかに定義されていると想定して続行します。構造体を定義せずに使用した場合のみ、エラーが発生します。

の場合typedefも同様です。

于 2012-11-29T13:01:07.007 に答える
1

いわゆる前方宣言です。前方宣言により、不完全な型が許可されているコンテキストでその名前を使用できます。

コンパイラは typedef タグを「認識」し、型が見つかるまでそれを格納します。そのため、typedef の後、使用前に型が宣言されている限り、問題ありません。

于 2012-11-29T13:05:58.433 に答える
1

特定の状況下では、struct ...型を宣言する前に使用することが有効です。いわゆる「不完全型」ですね。

たとえば、変数を「不完全な」構造体へのポインターとして宣言することは有効であり、(ご覧のとおり) typedef.

于 2012-11-29T13:00:27.827 に答える
-2

typedef 宣言を使用すると、int、float、double などの型指定子の代わりに使用できる独自の識別子を定義できます。typedef 宣言はストレージを予約しません。

詳細についてはhttp://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc03typdef.htm

于 2012-11-29T12:56:32.437 に答える