web-dev-qa-db-de.com

Was bedeutet ein Typ, gefolgt von _t (Unterstrich-t)?

Dies scheint eine einfache Frage zu sein, aber ich kann sie nicht mit der Stack Overflow-Suche oder Google finden. Was bedeutet ein Typ, gefolgt von einem _t? Sowie

int_t anInt;

Ich sehe viel in C-Code, der eng mit Hardware zu tun hat - ich kann nicht anders als zu denken, dass sie verwandt sind.

212
Kevin Griffin

Wie Douglas Mayle feststellte, bezeichnet er im Wesentlichen einen Typnamen. Daher wäre es nicht ratsam, Variablen- oder Funktionsnamen mit '_t' zu beenden, da dies zu Verwirrung führen kann. Der C89-Standard definiert neben size_t auch wchar_t, off_t, ptrdiff_t und wahrscheinlich einige andere, die ich vergessen habe. Der C99-Standard definiert viele zusätzliche Typen, wie z. B. uintptr_t, intmax_t, int8_t, uint_least16_t, uint_fast32_t usw. Diese neuen Typen sind formal in <stdint.h> definiert. Meistens verwenden Sie jedoch <inttypes.h>, der (ungewöhnlich für Standard-C-Header) <stdint.h> enthält. Es (<inttypes.h>) definiert auch Makros für die Verwendung mit printf() und scanf().

Wie Matt Curtis bemerkt hat, hat der Compiler im Suffix keine Bedeutung; es ist eine menschlich orientierte Versammlung.

Sie sollten jedoch auch beachten, dass POSIX viele zusätzliche Typnamen definiert, die auf '_t' enden, und das Suffix für die Implementierung reserviert. Das heißt, wenn Sie an POSIX-Systemen arbeiten, ist es nicht ratsam, Ihre eigenen Typnamen mit der Konvention zu definieren. Das System, an dem ich arbeite, hat es (seit mehr als 20 Jahren) gemacht; Wir werden regelmäßig von Systemen gestoßen, die Typen definieren, die denselben Namen haben wie wir.

171

Dies ist eine Konvention, die zum Benennen von Datentypen verwendet wird, z. B. mit typedef:


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

Der _t umschließt normalerweise eine undurchsichtige Typdefinition.

GCC fügt dem reservierten Namespace, den Sie möglicherweise nicht verwenden, lediglich Namen hinzu, die auf _t enden, um Konflikte mit zukünftigen Versionen von Standard C und POSIX zu vermeiden (GNU C library manual) . Nach einigen Recherchen habe ich endlich die richtige Referenz innerhalb des POSIX-Standards gefunden (1003.1, Begründung (informativ)):

B.2.12 Datentypen

Die Anforderung, dass zusätzliche in diesem Abschnitt definierte Typen mit "_t" enden, wurde durch das Problem der Namensraumverschmutzung verursacht. Es ist schwierig, in einer Header-Datei einen Typ zu definieren (wobei dieser Typ nicht durch IEEE Std 1003.1-2001 definiert ist) und in einer anderen zu verwenden, ohne dem Namensraum des Programms Symbole hinzuzufügen. Damit Implementierer ihre eigenen Typen bereitstellen können, müssen alle konformen Anwendungen verhindern, dass Symbole auf "_t" enden, sodass der Implementierer zusätzliche Typen bereitstellen kann. Da die Definition von Strukturelementen, die zu den in IEEE Std 1003.1-2001 definierten Strukturen hinzugefügt werden können (und in vielen Fällen müssen), eine Hauptverwendung von Typen darstellt, besteht ein zwingender Bedarf an zusätzlichen Typen.

Kurz gesagt, der Standard gibt an, dass gute Chancen bestehen, die Liste der Standardtypen zu erweitern. Daher schränkt der Standard den Namensraum _t für die eigene Verwendung ein.

Beispielsweise stimmt Ihr Programm mit POSIX 1003.1 Issues 6 überein, und Sie haben einen Typ foo_t definiert. POSIX 1003.1-Probleme 7 wird schließlich mit einem neu definierten Typ foo_t veröffentlicht. Ihr Programm stimmt nicht mit der neuen Version überein, was möglicherweise ein Problem darstellt. Das Einschränken der Verwendung von _t verhindert das Umgestalten des Codes. Wenn Sie also eine POSIX-Konformität anstreben, sollten Sie auf jeden Fall den _t vermeiden, wie es der Standard angibt.

Randnotiz: Ich persönlich versuche, mich an POSIX zu halten, weil ich denke, dass es gute Grundlagen für eine saubere Programmierung bietet. Außerdem mag ich Linux Coding Style (Kapitel 5) ziemlich gern. Es gibt einige gute Gründe, warum typedef nicht verwendet wird. Ich hoffe das hilft!

35
Benoit

Es ist eine Standardbenennungskonvention für Datentypen, die normalerweise durch Typedefs definiert wird. Viele C-Codes für Hardwareregister verwenden von C99 definierte Standardnamen für signierte und nicht signierte Datentypen fester Größe. Üblicherweise befinden sich diese Namen in einer Standard-Header-Datei (stdint.h) und enden mit _t.

16
mkClark

Der _t hat an sich keine besondere Bedeutung. Es ist jedoch allgemein üblich, das Suffix _t zu typedefs hinzuzufügen.

Sie sind vielleicht mit den gängigen C-Praktiken für die Benennung von Variablen besser vertraut ... Ähnlich wie es üblich ist, ap für einen Zeiger an der Spitze zu halten und einen Unterstrich vor globalen Variablen zu verwenden (dies ist etwas seltener) und um die Variablennamen i, j und k für temporäre Schleifenvariablen zu verwenden.

Im Code, bei dem die Wortgröße und -reihenfolge wichtig ist, werden häufig benutzerdefinierte Typen verwendet, die explizit sind, beispielsweise BYTEWord (normalerweise 16 Bit) DWORD (32 Bit). 

int_t ist nicht so gut, weil die Definition von int von Plattform zu Plattform variiert - also wessen int Sie konform sind? (Obwohl heutzutage die meisten PC-centric-Entwicklungen dies mit 32 Bit behandeln, behandeln viele Dinge für die Nicht-PC-Entwicklung immer noch Integer mit 16 Bit). 

11
Toybuilder

Es bedeutet Typ. size_t ist der Größentyp.

9
Douglas Mayle

Es ist nur eine Konvention, die "Typ" bedeutet. Es bedeutet dem Compiler nichts Besonderes.

9
Matt Curtis

Es gab einige gute Erklärungen zu diesem Thema. Fügen Sie einfach einen weiteren Grund hinzu, um die Typen neu zu definieren:

In vielen eingebetteten Projekten werden alle Typen neu definiert, um die angegebene Größe für die Typen korrekt anzugeben und die Portierbarkeit auf verschiedenen Plattformen (d. H. Compiler für Hardwaretypen) zu verbessern.

Ein weiterer Grund besteht darin, Ihren Code für verschiedene Betriebssysteme portierbar zu machen und Kollisionen mit vorhandenen Typen des Betriebssystems zu vermeiden, die Sie in Ihren Code integrieren. Dazu wird in der Regel ein eindeutiges (möglichst mögliches) Präfix hinzugefügt.

Beispiel:

typedef unsigned long dc_uint32_t;
8
Ilya

Wenn Sie sich mit Hardware-Schnittstellencode beschäftigen, hat der Autor des Codes, den Sie betrachten, int_t möglicherweise als bestimmte Ganzzahl für die Größe definiert. Der C-Standard weist dem int-Typ keine bestimmte Größe zu (dies hängt möglicherweise von Ihrem Compiler und der Zielplattform ab). Durch die Verwendung eines bestimmten int_t-Typs wird dieses Problem der Portabilität vermieden.

Dies ist eine besonders wichtige Überlegung für den Hardwareschnittstellencode, weshalb Sie die Konvention dort zum ersten Mal bemerkt haben.

6
Greg Hewgill

Zum Beispiel in 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 bedeutet immer definiert durch typedef.

0
Jayhello