Forum: Compiler & IDEs Präprozessor Textersetzung defines Prototypen


von Imperator (Gast)


Lesenswert?

Servus,
ich möchte mein Programm portabler machen. Will irgendwie nicht so 
richtig funktionieren.
1
//file1.h Prototypen
2
#ifndef FILE1_H
3
#define FILE1_H
4
extern void x_set(void);
5
extern void x_get(void);
6
extern void x_clear(void);
7
...
8
#endif
9
10
//file1.c Definition
11
#include "file1.h"
12
void x_set(void){}
13
void x_get(void){}
14
void x_clear(void){}
15
...
16
17
//file2.h neue Deklaration, Namensgebung
18
#ifndef FILE2_H
19
#define FILE2_H
20
21
#ifdef FILE1_H
22
#include "file1.h"
23
#define y         x
24
#else
25
#error "You must use either FILE1_H or ... define!"
26
#endif
27
28
void test(void);
29
30
extern void y_set(void);
31
extern void y_get(void);
32
extern void y_clear(void);
33
...
34
#endif
35
36
37
//file2.c Funktionen Aufruf
38
#include "file2.h"
39
void test(void){
40
  y_set();   //oder x_set() sollte hier gehen
41
  y_get();
42
  y_clear();
43
}

Wie könnte man mithilfe des Präprozessors die Namensgebung schlau 
ändern?
Oder sollte man immer den kompletten Namen ersetzen:
1
#define y_set       x_set
2
#define y_get       x_get
3
#define y_clear     x_clear

von PittyJ (Gast)


Lesenswert?

Ich verzichte, bis auf die Include-Guards, komplett auf Defines und 
Macros.
Man kann damit viel zu viel kaputt machen. Programme die keiner 
versteht, unvorhersehbare Effekte etc.

Auf keine Fall die Funktionsnamen über Preprozessor ändern. Spätestens 
in einer Woche blickt da keiner mehr durch!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Imperator schrieb:
> #ifdef FILE1_H
> #include "file1.h"

Das widerspricht sich. "FILE1_H" ist definiert, wenn "file1.h" 
eingebunden wurde, also wird "file1.h" nicht eingebunden, denn FILE1_H 
ist nicht definiert ...


> #define y         x

Das funktioniert nicht, nicht um y_set aus x_set zu gewinnen oder 
umgekehrt.


Wozu soll das ganze wirklich gut sein?

"Vereinfachen" tut's jedenfalls so nichts.

von Imperator (Gast)


Lesenswert?

Es geht um eine led library. Ich möchte mithilfe eines einzelnen 
defines, unabhängig verschiedener led-typen, dasselbe Programm 
ansteuern.

Ich bin auch weiter gekommen.
1
#define y_set       x_set
2
#define y_get       x_get
3
#define y_clear     x_clear

Funktioniert gut. Einzelne Literale wollte der Präprozessor nicht 
ersetzen.

Wenn man halt auf y_set(); 'open Declation' geht, dann wandert man auf 
das dazugehörige define x_set. Wiederum ein weiteres 'open Declation' 
spring auf die gewünschte Deklaration.

Ich bin jetzt zufrieden.

von a.s (Gast)


Lesenswert?

PittyJ schrieb:
> Ich verzichte, bis auf die Include-Guards, komplett auf Defines und
> Macros.

Naja, dann wirst Du wohl C++ schreiben
oder nur kleinen und Plattform- und Varianten-unabhängigen Code 
schreiben.

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


Lesenswert?

Imperator schrieb:
> Einzelne Literale wollte der Präprozessor nicht ersetzen.

Geht mit dem Verkettungsoperator ##
1
#define X_set(x) x ## _set
2
3
...
4
X_set(a) // => a_set

Aber wie oben schon geschrieben wurde: wenn man das nicht sehr sauber
und klar strukturiert und dokumentiert, dann blickt da später keiner
mehr durch.

: Bearbeitet durch Moderator
von Bernd K. (prof7bit)


Lesenswert?

Imperator schrieb:
> Ich bin auch weiter gekommen.
> #define y_set       x_set
> #define y_get       x_get
> #define y_clear     x_clear

Hör auf, bitte! Ich ahne daß sich das ganz schnell zu einer ganz üblen 
Code-Obfuskation auswachsen könnte. Das bekommst Du später kaum noch weg 
und die damit einhergehenden Beschwerden können wirklich höllisch sein.

Wenn Du Schreibarbeit für langweiligen und sich zig fach selbstähnlich 
wiederholenden Boilerplate sparen willst dann denk doch mal drüber nach 
code (echten Code, keine Makros) von einem übersichtlichen Python (oder 
sonstigen) Script erzeugen zu lassen, du kannst dann da tonnenweise 
getter und setter automatisch erzeugen lassen und solange das Ergebnis 
dann als echte .c oder .h ohne Makros dort steht kann man es sogar lesen 
und schmerzfrei debuggen.

: Bearbeitet durch User
von Imperator (Gast)


Lesenswert?

@Jörg Wunsch (dl8dtl) (Moderator)

Tatsächlich. Es läuft.
1
#define disp_clear_all_leds(disp)     disp ## _clear_all_leds
2
3
//Aufruf
4
disp_clear_all_leds(apa102)(10);

Vielen Dank. Das Läuft super. Aber ich denke ich bleibe lieber bei copy 
und past. Der Aufruf sieht doch etws bescheiden aus.

Obwohl, wenn man noch weiter verschachtelt:
1
clear_all_leds    disp_clear_all_leds(apa102)
2
3
//Aufruf
4
clear_all_leds(10);

Sieht schon super aus und funktioniert auch. Aber die IDE findet die 
Funktionsdefinition nicht.

von Bernd K. (prof7bit)


Lesenswert?

Imperator schrieb:
> Sieht schon super aus und funktioniert auch. Aber die IDE findet die
> Funktionsdefinition nicht.

Siehst Du, es fängt schon an. Hör auf bevor es noch schlimmer wird.

von PittyJ (Gast)


Lesenswert?

a.s schrieb:
> PittyJ schrieb:
>> Ich verzichte, bis auf die Include-Guards, komplett auf Defines und
>> Macros.
>
> Naja, dann wirst Du wohl C++ schreiben
> oder nur kleinen und Plattform- und Varianten-unabhängigen Code
> schreiben.

Ich verdiene sein 25 Jahren mein Geld mit C/C++ Code.
C++ hilft schon viel weiter.
Und ich habe z.B. eine Bibliothek, die läuft auf ARM, Mips und 64 Bit 
Intel.
Und alles ohne Macros.

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


Lesenswert?

PittyJ schrieb:
> C++ hilft schon viel weiter.

Allerdings sind Template-Fehlermeldungen oft mindestens genauso
kryptisch wie Makro-verursachte Fehlermeldungen.

von Rolf Magnus (Gast)


Lesenswert?

Jörg W. schrieb:
> PittyJ schrieb:
>> C++ hilft schon viel weiter.
>
> Allerdings sind Template-Fehlermeldungen oft mindestens genauso
> kryptisch wie Makro-verursachte Fehlermeldungen.

Gerade bezüglich Makros haben sich die Compiler-Meldungen bei gcc in den 
letzten Versionen deutlich verbessert.

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.