これは単純な質問のように思えますが、Stack Overflow検索やGoogleで見つけることはできません。タイプの後に_t
が続くとはどういう意味ですか?といった
int_t anInt;
ハードウェアに密接に対処することを意図したCコードでよく見かけます。それらは関連していると思わざるを得ません。
ダグラス・メイルが述べたように、それは基本的にタイプ名を示します。したがって、混乱を引き起こす可能性があるため、変数名または関数名を '_t
'で終了することはお勧めできません。 size_t
に加えて、C89標準はwchar_t
、off_t
、ptrdiff_t
、およびおそらく忘れてしまった他のいくつかを定義しています。 C99標準では、uintptr_t
、intmax_t
、int8_t
、uint_least16_t
、uint_fast32_t
など、多くの追加の型が定義されています。これらの新しい型は<stdint.h>
で正式に定義されていますが、ほとんどの場合、<inttypes.h>
を使用します(通常は標準Cヘッダーでは<stdint.h>
が含まれます)。 It(<inttypes.h>
)は、printf()
およびscanf()
で使用するマクロも定義します。
Matt Curtisが指摘したように、接尾辞にはコンパイラーにとって意味はありません。それは人間指向の慣例です。
ただし、 POSIX は '_t
'で終わる多くの追加の型名を定義し、は接尾辞を予約することにも注意してください実装用。つまり、POSIX関連のシステムで作業している場合、独自の型名を規則で定義することはお勧めできません。私が取り組んでいるシステムはそれを行ってきました(20年以上)。私たちが定義したのと同じ名前の型を定義するシステムによって定期的にトリップされます。
これは、データ型の命名に使用される規則です(例:typedef
):
typedef struct {
char* model;
int year;
...
} car_t;
_t
は通常、不透明(OPAQUE)型定義をラップします。
GCCは、使用しない可能性のある予約済み名前空間に_t
で終わる名前を追加するだけで、Standard CおよびPOSIXの将来のバージョンとの競合を回避します (GNU Cライブラリマニュアル) 。いくつかの調査の後、私はついにPOSIX標準(1003.1、根拠(参考))内で正しい参照を見つけました。
B.2.12データ型
このセクションで定義されている追加のタイプが「_t」で終わるという要件は、名前空間の汚染の問題によって促されました。 1つのヘッダーファイルで型(IEEE Std 1003.1-2001で定義されている型ではない)を定義し、プログラムの名前空間にシンボルを追加せずに別のヘッダーファイルで使用することは困難です。実装者が独自のタイプを提供できるようにするには、準拠するすべてのアプリケーションで「_t」で終わる記号を避ける必要があります。これにより、実装者は追加のタイプを提供できます。タイプの主な使用法は、IEEE Std 1003.1-2001で定義された構造に追加できる(多くの場合必要な)構造メンバーの定義にあるため、追加のタイプの必要性は説得力があります。
一言で言えば、規格は規格タイプのリストを拡張する可能性が十分にあると述べているため、規格は_t
名前空間を独自の使用に制限しています。
たとえば、プログラムはPOSIX 1003.1 Issues 6と一致し、タイプfoo_t
を定義しました。 POSIX 1003.1の問題7は最終的に新しい定義タイプfoo_t
でリリースされます。プログラムが新しいバージョンと一致しないため、問題がある可能性があります。 _t
の使用を制限すると、コードをリファクタリングできなくなります。したがって、POSIX準拠を目指している場合は、規格で定められている_t
を絶対に避ける必要があります。
サイドノート:個人的に、私はPOSIXに固執しようとします。なぜなら、それはクリーンなプログラミングのための良い基礎を与えると思うからです。さらに、私は Linux Coding Style(第5章) ガイドラインが大好きです。 typedefを使用しない理由はいくつかあります。この助けを願っています!
これは、通常typedefによって定義されるデータ型の標準の命名規則です。ハードウェアレジスタを扱うCコードの多くは、符号付きおよび符号なしの固定サイズデータ型にC99定義の標準名を使用しています。規則として、これらの名前は標準ヘッダーファイル(stdint.h)にあり、_tで終わります。
_t
には本質的に特別な意味はありません。しかし、_t
接尾辞をtypedefに追加するために一般的に使用されています。
変数の命名に関する一般的なCの慣習に精通しているかもしれません...これは、ポインタの前にapを付け、グローバル変数の前にアンダースコアを使用する方法に似ています(これは少し一般的ではありません) 、および変数名i
、j
、およびk
を一時ループ変数に使用します。
ワードサイズと順序が重要なコードでは、BYTE
Word
(通常16ビット)DWORD
(32ビット)。
int_t
はあまりよくありません。なぜなら、int
の定義はプラットフォームによって異なるため、誰がint
に準拠していますか? (最近では、ほとんどのPC中心の開発では32ビットとして扱われますが、非PC開発の多くのものはintを16ビットとして扱います)。
「タイプ」を意味する単なる慣習です。コンパイラにとって特別なことは何も意味しません。
タイプを意味します。 size_t
はサイズタイプです。
主題についてのいくつかの良い説明がありました。型を再定義する別の理由を追加するだけです:
多くの組み込みプロジェクトでは、すべてのタイプが再定義されて、指定されたサイズをタイプに正しく指定し、異なるプラットフォーム間での移植性を向上させます(つまり、ハードウェアタイプコンパイラ)。
別の理由は、異なるOS間でコードを移植可能にし、コードに統合しているOSの既存の型との衝突を避けるためです。このために、通常、一意の(可能な限り)プレフィックスが追加されます。
例:
typedef unsigned long dc_uint32_t;
ハードウェアインターフェイスコードを扱っている場合、見ているコードの作成者はint_t
を特定のサイズの整数として定義している可能性があります。 C規格は特定のサイズをint
型に割り当てておらず(コンパイラとターゲットプラットフォームに依存する可能性があります)、特定のint_t
型を使用すると移植性の問題を回避できます。
これは、ハードウェアインターフェイスコードの特に重要な考慮事項であり、これが最初にそこの規則に気付いた理由かもしれません。
たとえば、C99の/usr/include/stdint.h:
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
#ifndef __uint32_t_defined
typedef unsigned int uint32_t;
# define __uint32_t_defined
#endif
#if __WORDSIZE == 64
typedef unsigned long int uint64_t;
#else
__extension__
typedef unsigned long long int uint64_t;
#endif
_t
は常にtypedefによる定義を意味します。