Forum: PC-Programmierung [C] Funktionen in Abhängigkeit von defines kompilieren


von B. S. (bestucki)


Lesenswert?

Hallo zusammen,
Erstmal Code, die Problembeschreibung steht ganz unten.


Angenommen, ich habe folgendes Header-File foo.h:
1
#ifndef FOO_H_
2
#define FOO_H_
3
4
#include <stdint.h>
5
6
foo_a(uint8_t data);
7
foo_b(uint16_t data);
8
foo_c(uint32_t data);
9
10
#endif /* FOO_H_ */
11
12
#ifndef FOO_D_INCLUDED
13
  #ifdef FOO_D
14
    #define FOO_D_INCLUDED
15
    void foo_d(uint24_t data);
16
  #endif /* FOO_D */
17
#endif /* FOO_D_INCLUDED */
18
#undef FOO_D
19
20
#ifndef FOO_E_INCLUDED
21
  #ifdef FOO_E
22
    #define FOO_E_INCLUDED
23
    void foo_e(uint64_t data);
24
  #endif /* FOO_E */
25
#endif /* FOO_E_INCLUDED */
26
#undef FOO_E


Dies ist dann das dazugehörige Source-File foo.c:
1
#ifdef FOO_D_INCLUDED
2
void foo_d(uint24_t data){
3
.
4
.
5
.
6
}
7
#endif /* FOO_D_INCLUDED */
8
9
#ifdef FOO_E_INCLUDED
10
void foo_e(uint64_t data){
11
.
12
.
13
.
14
}
15
#endif /* FOO_E_INCLUDED */


In einer anderen Source steht dann folgendes:
1
#define FOO_E
2
#include <foo.h>

In irgendeiner anderen dann:
1
#define FOO_D
2
#define FOO_E
3
#include <foo.h>


Nun zu meiner Frage:
Werden die beiden Funktionen in jedem Fall eingefügt und somit 
kompiliert oder hängt dies vom Präprozessor ab? Ich könnte mir gut 
vorstellen, dass dies von der Abarbeitungsreienfolge der einzelnen Files 
abhängen könnte, welche Funktionen nun wirklich eingefügt werden. Oder 
wie handhabt dies der Präprozessor?

Gibt es eine andere sinnvolle (evt. bessere) Möglichkeit, Funktionen in 
Abhängigkeit von defines einzufügen? Hier geht es vor allem darum, dass 
nicht alle Compiler die Datentypen uint24_t und uint64_t kennen und ich 
Funktionen, die diese Datentypen benutzen, mit defines zum Projekt 
hinzufügen möchte, ohne dabei foo.h oder foo.c zu ändern.


Ich hoffe, ich konnte mein Problem einigermassen verständlich 
ausdrücken.
Vielen Dank für eure Hilfe!

von Malte S. (maltest)


Lesenswert?

Die defines in foo.c greifen beim Compilieren von foo.c. Ob in foo.h 
jetzt beim Compilieren von bar.c foo_d sichtbar ist oder nichts mag sich 
auf bar.c auswirken, aber niemals auf das aus foo.c entstandene 
Objektfile. Wenn du verschiedene Varianten von foo.o brauchst, musst du 
foo.c entsprechend mit verschiedenen defines compilieren und z.B. die 
Objetcs verschieden benennen oder platzieren.
Aber: wenn das vom Compiler abhängig ist, nimm doch an allen Stellen die 
üblichen defines zur Erkennung eines Compilers. Beim Wechsel der 
Toolchain musst du eh im Zweifelsfall alles neu compilieren.

von B. S. (bestucki)


Lesenswert?

Vielen Dank für deine Antwort. Da hab ich wohl zu wenig weit gedacht...

Dank deines Vorschlags die Erkennung des Compilers zu verwenden, hatte 
ich gleich eine andere Idee: Da ich stdint.h verwende, müssen die 
Grenzen der Datentypen definiert worden sein. Dahr kann ich auf 
UINT8_MAX etc. testen. Somit muss ich auch nicht die Files ändern, wenn 
die Funktionen in einem anderen Projekt mit einem anderen Compiler 
verwendet werden.

Vielen Dank für den Denkanstoss!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

be stucki schrieb:
> Dahr kann ich auf
> UINT8_MAX etc. testen.

Dieser Wert dürfte bei allen Compilern gleich sein.

von B. S. (bestucki)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Dieser Wert dürfte bei allen Compilern gleich sein.

Sorry, hab mich wohl zu wenig genau ausgedrückt. Ich prüfe nur mit
1
#ifdef UINT24_MAX
2
  void foo_d(uint24_t data);
3
#endif /* UINT24_MAX */
auf das Vorhandensein der Definition. Bei Compilern, die keine 24 oder 
64 Bit Integer verwenden, wird wohl UINT24_MAX und UINT64_MAX nicht 
definiert worden sein. Hoffe ich zumindest...

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.