Forum: Compiler & IDEs typedef versus #define


von Peter (Gast)


Lesenswert?

Da ich beim programmieren sehr tipfaul bin, definiere ich gerne Kürzel 
für meine Integer Typen, zum Beispiel:

#define u08 unsigned char
#define s08 signed char

Natürlich geht das auch mit typedefs:

typedef unsigned char u08;
typedef signed char   s08;

Meine Frage: Gibt es einen funktionellen Unterschied zwischen den beiden 
Möglichkeiten? Wenn ja, welches sind die Vor- oder Nachteile der einen 
oder anderen Methode? Oder spielt es überhaupt keine Rolle?

von Tom (Gast)


Lesenswert?

Mit "define" definierte Namen werden vor dem eigentlichen compilieren 
mit einer Art "Suchen/Ersetzen" bearbeitet. Fehlermeldungen werden sich 
dann auf den erstezten Datentyp beziehen. Mit Typedef definierst du 
einen ganz neuen Datentyp.

von Karl H. (kbuchegg)


Lesenswert?

1) Du solltest versuchen, auf die Standardtypen
   umzuschalten anstatt deine eigenen Kürzel zu
   benutzen.
   uint8_t ist auch nicht viel länger als u08

2) Ja es gibt einen gravierenden Unterschied zwischen der
   #define Lösung und einer typedef Lösung, den Tom bereits
   angedeutet hat.

   Welchen Datentyp hat hier a, welchen hat b?
1
   #define pu08 unsigned char *
2
   pu08 a, b;
   (a ist ein unsigned char*, b ist ein unsigned char)

   Wie ist die Situation jetzt?
1
   typedef unsigned char * pu08;
2
   pu08 a, b;
   (sowohl a als auch b sind ein unsigned char*)

von Peter (Gast)


Lesenswert?

>uint8_t ist auch nicht viel länger als u08

2.33 mal länger ist für mich schon viel länger! (Zumindest sagt dass 
mein Chef, wenn ich um den 2.3 fachen Lohn bitte)

Üblicherweise nehme ich schon die neuen Standarttypen, soweit sie vom 
Compiler unterstürzt werden:

#define u08 uint8_t

Doch mit dem Pointerbeispiel hast Du ansich recht. Nur sowas würde ich 
nie machen, die *-chen tippen ich lieber selber, wenn ich sie brauche! 
(Die sind nicht länger als das 'p')


von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> sowas würde ich nie machen ...

Hat aber zuweilen Sinn.
1
typedef void (*sighandler_t)(int);
2
sighandler_t signal(int signum, sighandler_t handler);

fällt mir da spontan ein. ;-)  Hier nochmal die Variante ohne dem
typedef:
1
void (*signal(int signum, void (*handler)(int)))(int);

von Rolf Magnus (Gast)


Lesenswert?

@Jörg:

Also ich fand schon immer, daß die Version ohne typedef ihren ganz 
eigenen Charme hat. ;-)

@Peter:

>> uint8_t ist auch nicht viel länger als u08
>
> 2.33 mal länger ist für mich schon viel länger! (Zumindest sagt dass
> mein Chef, wenn ich um den 2.3 fachen Lohn bitte)

Also ich kauf dir einfach nicht ab, daß du durch die Verwendung von 
uint8_t statt u08 für das selbe Programm 2,3 mal soviel Zeit zum 
Programmieren brauchst.

von Peter (Gast)


Lesenswert?

>Also ich kauf dir einfach nicht ab, daß du durch die Verwendung von
>uint8_t statt u08 für das selbe Programm 2,3 mal soviel Zeit zum
>Programmieren brauchst.

Zum Programmieren nicht, aber für's eintippen von uint8_t brauch ich 
sogar 2.5 mal länger, weil ich noch die Shift-Taste für's Underscore 
benötige... smile

Trotzdem: Danke für eure Inputs!

von Ralf (Gast)


Lesenswert?

Hallo zusammen,

vor kurzem habe ich mal irgendwo gelesen (ich glaube auf embedded.com), 
dass Compiler (manche/alle ???) bei Standardtypen wie unsigned int 
besser den Code optimieren als bei typedef-Typen. Ist da was dran oder 
absoluter Blödsinn? Wenn das stimmt wäre ja die #define-Lösung evtl. 
besser.

Gruß,
Ralf

von Mikes (Gast)


Lesenswert?

Hallo,

ich dachte, dass ich die Zeiger & co. Thematik nun verstanden habe. Da 
kommt ein Herr Wunsch daher ;-), und lässt meine Seifenblase platzen. 
Kann mir jemand mal bitte kurz erläutern, was
1
typedef void (*sighandler_t)(int);
2
sighandler_t signal(int signum, sighandler_t handler);
oder
1
void (*signal(int signum, void (*handler)(int)))(int);

zu bedeuten hat?
definiert typedef einen Zeiger auf eine Prozedur die als Parameter ein 
"int" übergeben bekommt?

initialisiert
"sighandler_t signal(int signum, sighandler_t handler);"
einen Zeiger auf eine Prozedur "signal", die als Parameter ein "int" und 
einen Zeiger "handler" auf eine Prozedur erhält die als Parameter ein 
"int" übergeben bekommt?

Was um alles in der Welt bedeutet dann das letzte "(int)" in
1
void (*signal(int signum, void (*handler)(int)))(int);

Danke schonmal im Vorraus

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ralf wrote:

> vor kurzem habe ich mal irgendwo gelesen (ich glaube auf embedded.com),
> dass Compiler (manche/alle ???) bei Standardtypen wie unsigned int
> besser den Code optimieren als bei typedef-Typen.

Einen solchen Compiler würde ich für, ähem, minderwertig halten.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Mikes wrote:

> ich dachte, dass ich die Zeiger & co. Thematik nun verstanden
> habe. Da kommt ein Herr Wunsch daher ;-), und lässt meine
> Seifenblase platzen.

Och, das tut mir aber leid. ;-)

Das Beispiel fiel mir gerade nur so ein, ist Standard-Unix-API.

> definiert typedef einen Zeiger auf eine Prozedur die als Parameter
> ein "int" übergeben bekommt?

So ist es, und sie gibt nichts (void) zurück.

> initialisiert "sighandler_t signal(int signum, sighandler_t
> handler);" einen Zeiger auf eine Prozedur "signal", die als
> Parameter ein "int" und einen Zeiger "handler" auf eine Prozedur
> erhält die als Parameter ein "int" übergeben bekommt?

Es initialisiert nichts, es deklariert nur, und zwar dass es eine
Funktion namens signal() gibt, die zwei Parameter übergeben bekommt.
Der erste ist vom Typ int, der zweite ist besagter Funktionszeiger.
Zurück gibt sie ebenso einen Funktionszeiger (nämlich den alten signal
handler, der zuvor installiert gewesen ist).

> Was um alles in der Welt bedeutet dann das letzte "(int)" in
>
1
> void (*signal(int signum, void (*handler)(int)))(int);
2
>

Dass die Funktion, deren Zeiger signal() zurückgibt, halt als Paramter
einen int hat. ;-)

p.s.: da fällt mir gerade das Program "cdecl" wieder ein:
1
$ cdecl
2
Type `help' or `?' for help
3
explain void (*signal(int, void (*)(int)))(int)
4
declare signal as function (int, pointer to function (int) returning void) returning pointer to function (int) returning void

von Rolf Magnus (Gast)


Lesenswert?

Man kann's auch so sagen:

Der Typ des Zeigers auf einen Signalhandler ist:

void (*handler)(int);

Wenn ich jetzt eine Funktion haben will, die einen int als Parameter hat 
und deren Rückgabetyp dieser Zeiger ist, muß ich 'handler' durch 
Funktionsnamen und Parameterliste ersetzen, also:

void (*funktion1(int))(int);

Das erste int ist der Parameter von funktion1, das zweite int ist der 
Parameter des Handlers.
Soll die Funktion jetzt auch noch einen zweiten Parameter bekommen, der 
vom Signalhandlertyp ist, muß ich den in die Parameterliste aufnehmen:

void (*funktion2(int, void (*)(int)))(int);

Mit Parameternamen dann eben:

void (*signal(int signum, void (*handler)(int)))(int);

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.