_t(下線-t)が後に続くタイプは何を表しますか?


261

これは簡単な質問のようですが、スタックオーバーフロー検索やGoogleでは見つかりません。タイプの後に_t意味とは何ですか?といった

int_t anInt;

ハードウェアと密接に対応することを目的としたCコードで多く見られます。それらは関連していると思わずにはいられません。


3
どこがint_t定義されていますか?常にとして定義されている場合intは、役に立ちません。int直接使用する方がはるかに明確です。それが常にintlong intまたはである可能性がある場合などshort int)として定義されていない場合は、選択が不十分で紛らわしい名前です。
キーストンプソン

回答:


213

Douglas Mayleが述べたように、それは基本的に型名を示します。その結果、_t混乱を招く可能性があるため、変数名または関数名を ' 'で終了することはお勧めできません。同様にsize_t、C89標準の定義wchar_toff_tptrdiff_t、と私は忘れてしまった、おそらくいくつかの他。C99標準の定義のような余分な種類の、たくさんのuintptr_tintmax_tint8_tuint_least16_tuint_fast32_t、など。これらの新しい型はで正式に定義されて<stdint.h>いますが、ほとんどの場合<inttypes.h>、(通常は標準のCヘッダーに)が含まれて<stdint.h>いるものを使用します。また、(<inttypes.h>)は、printf()およびで使用するマクロを定義しますscanf()

Matt Curtisが述べたように、接尾辞のコンパイラには意味がありません。それは人間指向の慣習です。

ただし、POSIXは ' _t'で終わる多くの追加の型名を定義し、実装用のサフィックス予約することにも注意する必要があります。つまり、POSIX関連のシステムで作業している場合は、独自の型名を規則で定義することはお勧めできません。私が取り組んでいるシステムはそれを(20年以上)行ってきました。定義したのと同じ名前のタイプを定義するシステムに定期的につまずかれます。


4
OSと一般的なランタイムライブラリが一般的な名前で型を定義することは理にかなっているようです。しかし、あなたの会社のタイプにもプレフィックスや何かを前に付けるべきではありませんか?
Toybuilder 2008年

17
私はtypedefで_tではなく_typeを使用して、それを回避しています。
CesarB

4
@Jonathan Leffler-ユーザー定義型にどのような命名規則を使用しますか?
J.アンドリューラフリン2011

15
@Andrew:プレフィックスとして使用するのに便利な省略形がある場合は、abbr_xxxxx_tタイプ名を使用しても安全です。そのような接頭辞がないと、いつでも捕まる可能性があります。一般的に、標準化_tのタイプは、すべて小文字を使用します(FILEDIR2つの例外、二度ある-すべて大文字、およびなし_t)あなたが使用できるよう、CamelCase_tまたは主要なキャップなし、適度な安全性。私が主に取り組んでいるシステムは_t、危険にさらされて使用される傾向がありますが、時々私たちを噛みました。私はCamelCase自分の作品に接尾辞なしで使用する傾向があります。私の関数は通常すべて小文字です。
ジョナサンレフラー

5
@JonathanLeffler、私はその規則、タイプにはキャメルケース、関数にはロワーケースを使い始めました。私は自分だけではないことを期待してこの質問を検索しました。検証ありがとうございます!
オースティンマリンズ2014年

50

これは、データ型の命名に使用される規則typedefです。


typedef struct {
  char* model;
  int year;
...
} car_t;


43

_t通常は不透明な型定義をラップします。

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第6号と一致し、タイプを定義したとしますfoo_tPOSIX 1003.1第7号は、新しく定義されたタイプで最終的にリリースされfoo_tます。プログラムが新しいバージョンと一致しないため、問題が発生する可能性があります。_t使用を制限すると、コードをリファクタリングできなくなります。したがって、POSIX準拠を目指す場合は_t、規格に明記されているように、必ずを回避する必要があります。

補足:個人的には、POSIXに固執しようとします。クリーンなプログラミングのための良い基礎を与えると思うからです。さらに、私はLinuxコーディングスタイル(第5章)ガイドラインをかなり気に入っています。typedefを使用しない理由はいくつかあります。この助けを願っています!


18

これは、通常typedefによって定義されるデータ型の標準の命名規則です。ハードウェアレジスタを扱う多くのCコードは、符号付きおよび符号なしの固定サイズデータ型にC99定義の標準名を使用しています。慣例として、これらの名前は標準ヘッダーファイル(stdint.h)にあり、_tで終わります。



11

_tは、本質的に特別な意味はありません。しかし_t、typedefにサフィックスを追加することは一般的な使用に陥っています。

変数の命名に関するCの一般的な慣例に慣れているかもしれません...これは、ポインターの前にapを​​付け、グローバル変数の前にアンダースコアを使用するのが一般的である方法に似ています(これは少し一般的ではありません) 、および変数名を使用するにはijと、k一時的なループ変数のため。

ワードサイズと順序が重要なコードでは、BYTE WORD(通常は16ビット)DWORD(32 ビット)などの明示的なカスタム定義型を使用するのが非常に一般的です。

int_tの定義はintプラットフォーム間で異なるため、あまり良くありません- intどちらに準拠していますか?(ただし、最近では、ほとんどのPC中心の開発では32ビットとして扱いますが、PC以外の開発では、intを16ビットとして扱います)。



8

主題についていくつかの良い説明がありました。タイプを再定義する別の理由を追加するだけです。

多くの組み込みプロジェクトでは、すべてのタイプが再定義されて、タイプに対する特定のサイズが正しく示され、さまざまなプラットフォーム(つまり、ハードウェアタイプコンパイラ)間の移植性が向上します。

別の理由は、さまざまなOS間でコードを移植可能にし、コードに統合しているOSの既存の型との衝突を回避するためです。このため、通常は一意の(可能な限り)接頭辞が追加されます。

例:

typedef unsigned long dc_uint32_t;

7

ハードウェアインターフェイスコードを扱っている場合は、調べているコードの作成者がint_t特定のサイズの整数であると定義している可能性があります。C標準は、int型に特定のサイズを割り当てません(コンパイラとターゲットプラットフォームに依存する可能性があります)int_t。特定の型を使用すると、移植性の問題を回避できます。

これは、ハードウェアインターフェイスコードの特に重要な考慮事項です。そのため、そこでの規則に最初に気付いたのかもしれません。


1
これはあまり良い方法ではありません。[u] int_ [32 16 8] _tを定義して、定義するサイズを明確にすることを期待します。
イリヤ

1
正解です。「int_t」はそれ自体がプログラマーに、ユーザー定義型であることを伝えますが、実際の型ではありません。
グレッグ・ヒューギル

0

たとえば、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によって定義されることを意味します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.