12

CとC++のtypedefおよびstruct名前空間では、コメントの1つは、 struct foo...の行に沿ってtypedefを使用するよりも、いくつかを公開する方が望ましいことを示唆しているようです。

typedef struct foo foo;

...そしてAPI全体のfoo代わりに使用します。struct foo

後者のバリアントに欠点はありますか?

4

6 に答える 6

9

唯一の欠点(*)は、構造体であるという事実を隠し、foo一部の組み込み型のエイリアスではないことです。

注(*):これがあなたにとってマイナス面であるかどうかは好みの問題です。

  • 完全に不透明にするのに適しています(以下の最初のコメントを参照)。
  • 一部の人々がこれが欠点であると考える理由を確認するには、Linuxカーネルのコーディングスタイル(typedefsの章)を確認してください。
于 2012-04-20T09:03:44.217 に答える
8

それはあなたがその言葉をどれだけ好きかによりますstructstruct thatとを自由に振りかけることでプログラムがより明確になると思われる場合は(もちろん、C ++では使用struct totherできません)、必ずそのバージョンを使用してください。struct thisstruct

個人的には、繰り返すことで何のメリットもないと思いますので、名前structだけを使ってよかったです。typedefまた、C ++はtypedef struct xyz xyz;宣言を効果的に自動的に提供するため(特にC ++で明示的に記述できるため、正確ではありませんが、十分に近いため、心配する必要はありません)、完璧になると思います。 Cでも同じように使用する意味があります。Cコンパイラはそれに満足しているので、私は通常、必要に応じtypedef struct tag tag;て使用してから使用tagtag *ます。


別の、しかし完全に維持可能なビューについては、Linuxカーネルコーディングスタイルガイドをお読みください。


typedefC2011では、同じタイプのエイリアスである限り、を再定義できることに注意してください。

ISO / IEC 9899:2011§6.7宣言

セマンティクス

¶5宣言は、一連の識別子の解釈と属性を指定します。識別子の定義は、次のような識別子の宣言です。

—オブジェクトの場合、ストレージはそのオブジェクト用に予約されます。

—関数の場合、関数本体を含みます。119)

—列挙定数の場合、は識別子の(唯一の)宣言です。

— typedef名の場合、は識別子の最初の(または唯一の)宣言です。

これが不可能だったC99と比較してください。

ISO / IEC 9899:1999§6.7宣言

セマンティクス

¶5宣言は、一連の識別子の解釈と属性を指定します。識別子の定義は、次のような識別子の宣言です。

—オブジェクトの場合、ストレージはそのオブジェクト用に予約されます。

—関数の場合、関数本体を含みます。98)

—列挙定数またはtypedef名の場合、は識別子の(唯一の)宣言です。

これにより、一貫性がある限り、型定義の作成が簡単になります(ただし、関連する各プラットフォームに十分な互換性のあるC2011コンパイラがある場合のみ)。

于 2012-04-20T09:12:18.953 に答える
7

typedef構造体タイプにするかどうかについて:

ここにいくつかの意見があります(すべてtypedefing構造に対して):

OpenBSDスタイルガイドから:

「構造体型にtypedefを使用することは避けてください。これにより、アプリケーションがそのような構造体へのポインターを不透明に使用できなくなります。これは、通常の構造体タグを使用する場合に可能であり、有益です。」

Linuxカーネルコーディングスタイルから:

「構造体とポインターにtypedefを使用するのは間違いです。」

Peter VanderLindenによるExpertCProgrammingから:

「構造体のtypedefを気にしないでください。構造体は、「構造体」という単語を書く手間を省くだけです。これは、とにかく隠してはいけない手がかりです。」

于 2012-04-20T09:19:16.643 に答える
2

それは多かれ少なかれ好みの問題です。

タグを宣言するだけstructで、同じスコープ内の変数、関数、または列挙子(または、混乱している場合は別のタイプ)に名前を使用することもできます。また、ユーザーは単語を記述する必要がありますstruct。これにより、コードがより明確になります。

タイプ名も宣言することで、入力structしたくない場合に入力しないようにすることができます。

他の質問での私のコメントは、structタグと同じ名前のポインター型の宣言に言及していました。

typedef struct foo * foo;

様式的には、これはポインタであるという事実を隠すため、少し不快です。これは、それがポインタであるという事実を隠します。これはAPIによって定義された不透明(OPAQUE)型であるという質問のコンテキストではおそらく問題ありませんが、私の意見では、非不透明(OPAQUE)型にはかなり失礼です。また、C++との互換性も失われます。その言語では、このような宣言は無効です。これは、個別のタグスペースではなく現在の名前空間にstruct foo導入され、その名前空間で同じ名前を持つ他のタイプの宣言を防ぐためです。foo

于 2012-04-20T09:13:15.797 に答える
1

命名規則に固執するだけで大​​丈夫です。

typedef struct
{
  //...
}              t_mytype;
//...
t_mytype thing;

このようにして、それがカスタムタイプであることがわかります。構造体である場合は、明示的な名前を使用するだけで、実際には使用しないでくださいt_mytype

于 2012-04-20T09:06:20.487 に答える
0

typedefに対するもう1つの論拠は、クリーンなヘッダーを作成することの難しさです。ヘッダーの例を見てみましょう。

#ifndef HEADER_H
#define HEADER_H
#include "s.h"
void f(struct s *);
#endif

このヘッダーは改善できます。確かに、struct s定義する必要はありません。したがって、次のように書くことができます。

#ifndef HEADER_H
#define HEADER_H
struct s;
void f(struct s *);
#endif

したがって、ユーザーはstruct s不透明な構造体として使用でき、"s.h"プライベートに保つことができます。

同じことをしましょうが、typedef

#ifndef HEADER_H
#define HEADER_H
typedef struct s s_t;
void f(s_t *);
#endif

この行typedef struct s s_tは、使用したいすべてのヘッダーに表示され、s_t *冗長なコードは嫌いです。これを回避する方法は複数ありますが、おそらく最も簡単なのはtypedefを取り除くことです。

于 2021-03-31T09:49:57.077 に答える