www.mikrocontroller.net

Forum: Compiler & IDEs typedef versus #define


Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?
   #define pu08 unsigned char *
   pu08 a, b;
   (a ist ein unsigned char*, b ist ein unsigned char)

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

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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')


Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> sowas würde ich nie machen ...

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

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

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Mikes (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
oder
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
void (*signal(int signum, void (*handler)(int)))(int);

Danke schonmal im Vorraus

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
>
> void (*signal(int signum, void (*handler)(int)))(int);
> 

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:
$ cdecl
Type `help' or `?' for help
explain void (*signal(int, void (*)(int)))(int)
declare signal as function (int, pointer to function (int) returning void) returning pointer to function (int) returning void

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.