C で構造体を頻繁に型定義する必要があるのはなぜですか?

Greg Hewgill が言ったように、typedef はもはや struct を書く必要がないことを意味します あらゆる所に。これにより、キーストロークが節約されるだけでなく、抽象化がわずかに向上するため、コードがよりクリーンになります。

のようなもの

typedef struct {
  int x, y;
} Point;

Point point_new(int x, int y)
{
  Point a;
  a.x = x;
  a.y = y;
  return a;
}

「struct」キーワードを至る所に表示する必要がない場合は、よりきれいになります。言語に「Point」と呼ばれる型が実際に存在するかのように見えます。 typedef の後に 、私が推測する場合です。

また、あなたの例(および私の例)は struct の名前付けを省略していることに注意してください それ自体、実際に名前を付けることは、不透明な型を提供する場合にも役立ちます。次に、ヘッダーに次のようなコードを記述します。たとえば、

typedef struct Point Point;

Point * point_new(int x, int y);

struct を指定します 実装ファイルの定義:

struct Point
{
  int x, y;
};

Point * point_new(int x, int y)
{
  Point *p;
  if((p = malloc(sizeof *p)) != NULL)
  {
    p->x = x;
    p->y = y;
  }
  return p;
}

この後者の場合、Point by 値を返すことはできません。これは、その定義がヘッダー ファイルのユーザーから隠されているためです。これは、たとえば GTK+ で広く使用されている手法です。

更新 この typedef の使用が高く評価されている C プロジェクトもあることに注意してください。 struct を隠す Linux カーネルはおそらく最もよく知られているプロジェクトです。 Linus の怒りの言葉については、The Linux Kernel CodingStyle ドキュメントの第 5 章を参照してください。 :) 私が言いたいのは、結局のところ、質問の「すべき」はおそらく確定していないということです.


これを勘違いしている人が驚くほど多いです。 C で構造体を型定義しないでください。これは、大規模な C プログラムですでに非常に汚染されているグローバル名前空間を不必要に汚染します。

また、タグ名のない typedef 構造体は、ヘッダー ファイル間の順序関係を不必要に強制する主な原因です。

考慮事項:

#ifndef FOO_H
#define FOO_H 1

#define FOO_DEF (0xDEADBABE)

struct bar; /* forward declaration, defined in bar.h*/

struct foo {
  struct bar *bar;
};

#endif

このような定義では、typedef を使用せずに、コンパイル ユニットが foo.h をインクルードして FOO_DEF を取得することができます。 意味。 foo の 'bar' メンバーを逆参照しようとしない場合 struct の場合、「bar.h」ファイルを含める必要はありません。

また、タグ名とメンバー名で名前空間が異なるため、次のような非常に読みやすいコードを書くことができます。

struct foo *foo;

printf("foo->bar = %p", foo->bar);

名前空間は分離されているため、構造体タグ名と一致する変数の名前付けに競合はありません。

私があなたのコードを保守しなければならない場合は、あなたの typedef 構造体を削除します。


Dan Saks による古い記事 (http://www.ddj.com/cpp/184403396?pgno=3) から:

リンクされた記事には、typedef を必要としない C++ の動作についての議論もあります。 微妙な名前の隠蔽問題を引き起こす可能性があります。これらの問題を防ぐには、typedef にすることをお勧めします。 一見不要に見えますが、C++ のクラスと構造体も同様です。 C++ では、typedef を使用して 名前の隠蔽は、潜在的な問題の隠れた原因ではなく、コンパイラが通知するエラーになります。