PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Preprocessor, bedingte Compilierierung



HaWe
11.12.2017, 11:04
hallo,
ich möchte per bedingter Compilierierung meinen Code für verschiedene Zielplattformen anpassen, ähnlich wie hier:


#define TARGET 3 // willkürlicher Wert je nach Zielplattform
#if TARGET==1
/* code wenn TARGET gleich 1 ist */
#elif TARGET==2
/* code wenn TARGET 2 ist */
#else
/* code wenn TARGET nicht 1 oder 2 ist*/
#endif

Der Wert der Konstanten für TARGET muss global im Kopf deklariert werden, also außerhalb von Funktionen.
Daneben müsen die #if / #elif -Abfrage ebenfalls im Kopf möglich sein (für weitere globale #define-Konstanten, die sich daraus ergeben), zusätzlich aber auch im Code selber.
- das geht mit den Zahlen-Konstanten auch soweit.

A-Bär:
meine Werte für TARGET sind nicht numerisch, sondern Buchstaben (U, M, Z, D oder E) -
wie muss ich dann TARGET #definieren? und wie lauten dann die zugehörigen #if / #elif Abfragen?
#define TARGET Z
#if TARGET==Z // ???
#if TARGET=='Z' // ???

oder
#define TARGET 'Z'
#if TARGET==Z // ???
#if TARGET=='Z' // ???

oder
const char TARGET = 'Z';

und wie lauten dann die zugehörigen #if / #elif Abfragen?

oder geht das gar nicht mit Buchstaben oder C strings?

Ceos
11.12.2017, 11:05
ich würde ehrlich gesagt garnicht erst mit buchstaben und zahlen als abfragewert arbeiten

ein einfache existensabfrage für das makro reicht schon ala

#define CASE_A oder #define CASE_B
und die abfragen per
#ifdef CASE_A
...
#else ifdef CASE_B
...
#endif
würde da schon reichen

HaWe
11.12.2017, 11:07
ich würde ehrlich gesagt garnicht erst mit buchstaben und zahlen als abfragewert arbeiten

ein einfache existensabfrage für das makro reicht schon ala

#define CASE_A oder #define CASE_B
und die abfragen per
#ifdef CASE_A
...
#else ifdef CASE_B
...
#endif
würde da schon reichen

das ist im Handling zu schwierig, insbes. auch für die Folge- #defines/#if/#elif
Daher müssen die Konstanten wechselnde Werte annehmen können, nicht nur "definiert sein".

PS, edit:
Was mir nicht klar ist, ist allerdings, ob das was sich hinter TARGET versteckt für den Preprocessor sowie immer schon nur (ggf. sogar verschieden lange) Zeichenketten sind, die mit == verglichen werden. Von daher wäre dann ein Z nichts anders als eine 2 oder zusammengesetze Konstanten wie M0 oder DUE oder was auch immer.

Ceos
11.12.2017, 11:16
das ist im Handling zu schwierig

ansichtssache, ich finde die andere richtung problematischer aber du könntest dir ein beispiel and en arduino libs nehmen die machen heftigstens gebrauch davon :)

HaWe
11.12.2017, 11:19
ansichtssache, ich finde die andere richtung problematischer aber du könntest dir ein beispiel and en arduino libs nehmen die machen heftigstens gebrauch davon :)

welche? ich habe bisher noch keine praktische Erfahrung mit so etwas. Auch das oberste Beispiel mit den Zahlen stammt aus einem Tutorial.

Ceos
11.12.2017, 11:39
also ich habe einen artikel gefudnen der sagt dass es nicht geht, nur mit umwegen und mangels arduino lib hab ich mal meine atmel libs befragt und die amchen ebenfalls den umweg über ifdef oder zahlenersetzungen

damit wird aus -mmcu=atxmega128a4u -> #ifdef _AVR_ATXMEGA128A4U über eine funktion des avr-gcc

ich ahbe das bei arduino ähnlich gesehen, lass dir doch mal die befehlszeile für deinen compiler anzeigen und such nach der boardbezeichnung und suche dann im ganzen projekt danach, vielleicht hilft das

https://stackoverflow.com/questions/2335888/how-to-compare-strings-in-c-conditional-preprocessor-directives

HaWe
11.12.2017, 12:27
also ich habe einen artikel gefudnen der sagt dass es nicht geht, nur mit umwegen und mangels arduino lib hab ich mal meine atmel libs befragt und die amchen ebenfalls den umweg über ifdef oder zahlenersetzungen

damit wird aus -mmcu=atxmega128a4u -> #ifdef _AVR_ATXMEGA128A4U über eine funktion des avr-gcc

ich ahbe das bei arduino ähnlich gesehen, lass dir doch mal die befehlszeile für deinen compiler anzeigen und such nach der boardbezeichnung und suche dann im ganzen projekt danach, vielleicht hilft das

https://stackoverflow.com/questions/2335888/how-to-compare-strings-in-c-conditional-preprocessor-directives

ich will ja nicht über #ifdef arbeiten, sondern über #if TARGET==...

aber tatsächlich scheint es jetzt mit Buchstaben genau so zu klappen wie mit Zahlen, offenbar ist für den pp doch alles nur eine Zeichenkette.
(Zuerst hatte es nicht geklappt . jetzt aber doch, wschl war ein typo die Urasche... ich probiere aber jetzt auch die anderen Konstanten-Werte durch...)

- - - Aktualisiert - - -

edit,
ja, zuerst scheint der pp im Code bei
#define TARGET Z
das Vorkommen von TARGET "blind" durch Z zu ersetzen, und dann überprüft er
#if Z==Z
//...
#elif Z==D
//...
was eben True oder False ist. So wäre das stimmig.

- - - Aktualisiert - - -

nee, geht doch nicht.
Ich muss dann wohl bei den Zahlen bleiben, oder?

Ceos
11.12.2017, 12:34
siehe artikel und beispiele darin :)

HaWe
11.12.2017, 12:46
hmm, da sind in der Diskussion eindeutig zuviele Buchstaben mit unverständlichem Wenn und Aber und teilw auch völlig ohne verständlichen Sinn.

Das hier mit den Hochkommata scheint aber doch am aussichtsreichsten zu sein - oder verstehe ich das falsch:
#define CHOICE 'J'
#if 'J' == CHOICE
//...

Ceos
11.12.2017, 12:55
nein das Beispiel war einfacher


#define OPTION_A 1
#define OPTION_B 2
^^^^^^^^^^^^^ das sind deine wortersetzungen für ziffern, man könnte auch enumeration dazu sagen

define SELECTED OPTION_A
damit triffst du die wahl ... kann auch außerhalb in den compiler settings passieren

#if SELECTED==OPTION_A
#elif SELECTED==OPTION_B
#endif


für den PC sieht dass dann aus dass OPTION_A durch eine 1 und OPTION_B durch eine 2 ersetzt werden und du bei #define SELECTED XXXXXX eine Zahl zur Auswahl eingibts

Du kannst Makros in Makros in Markos in Markso verwenden ... das geht zwar ein wenig zu Weit aber wenn du mal von X Makros hörst, lass dir gesagt sein .. sie sind MÄCHTIG ... aber auch mächtig kompliziert

HaWe
11.12.2017, 13:10
kapier ich nicht, was du damit sagen willst, das ist mir zu hoch und viel zu sehr verkompliziert.
Was geht ist das:
#define TARGET 1
#if TARGET==1


Die Frage ist, ob die Entsprechung für Buchstaben dies hier ist:
#define TARGET 'Z'
#if TARGET=='Z' // ???

Ceos
11.12.2017, 13:18
entschuldige, noch einfacher kann ich es nicht erklären als dass

#define Option_A 1

bedeutet dass der Begriff "Option_A" durch eine "1" ersetzt wird, also als beispiel zu dem was ich geschrieben habe

#define OPTION_A 1

wenn ich im Code "OPTION_A" schreibe macht er eine "1" draus

#define OPTION_A 1
#define MARKO_1 OPTION_A
#define MAKRO_2 MAKRO_1
....
#define MAKRO_1234 MAKRO_1233

wenn ich jetzt "MAKRO_1234" im Code verwende wird immernoch eine "1" draus, denn MAKRO_1234 = MAKRO_1233 = .... = MAKRO_1 = OPTION_A = 1

also ist #if MAKRO_200==1 > TRUE genauso wie #if MAKRO_200==OPTION_A

wenn dir der begriff enumeration bekannt ist sollte das eigentlich nicht schwer zu verstehen sein

wenn es doch zu kompliziert klingt, akzeptiere bitte meine antwort: "Es geht nicht!" ... ich habe dieses mal sogar von anfang an referenzen serviert um es zu belegen!

HaWe
11.12.2017, 13:24
verstehe ich nicht, warum so kompliziert?
ich habe doch gar keine 3 #define Makros
#define OPTION_A 1
#define MARKO_1 OPTION_A
#define MAKRO_2 MAKRO_1

ich habe lediglich 1 Makronamen
#define TARGET 1
den ich abfragen will, und das soll anstatt Zahlen jetzt Buchstaben abfragen können. also stattdessen
#define TARGET 'Z'

Ceos
11.12.2017, 13:27
wenn es doch zu kompliziert klingt, akzeptiere bitte meine antwort: "Es geht nicht!"
es geht nur über den umweg deine buchstaben als zahlen zu codieren

dann mach halt
#define A 1
#define B 2
#define C 3

ABER (ACHTUNG WICHTIG) bedenke dass JEDES MAL wenn du ein A Schreibst plötzlich eine 1 dafür gesetzt wurd und wenn du B schreibst plötzlich eine 2

Deswegen würde dieser weg keinen sinn machen!


FAZIT (damit kannst du das Thema als erledigt markieren): Es geht nicht, der Precompiler kann nur mit Zahlen arbeiten

HaWe
11.12.2017, 13:31
#define A 1
#define B 2
#define C 3

ich habe keine 3 verschiedenen Makros, nur 1 !!
den Wert passe ich an und setze ihn ein, wenn ich aktuell ein bestimmtes Board angesteckt habe, zum Hochladen.
Anderes Bord = anderer Wert für TARGET, dann ebenfalls neu komp.+hochladen.

ABER (ACHTUNG WICHTIG) bedenke dass JEDES MAL wenn du ein A Schreibst plötzlich eine 1 dafür gesetzt wurd und wenn du B schreibst plötzlich eine 2
genau deswegen nenne ich mein Makro ja auch TARGET und nicht A oder B, was ja sonst Unsinn wäre.

Und warum soll eine Zahl gehen, aber kein Buchstabe?

Ceos
11.12.2017, 13:37
Und warum soll eine Zahl gehen, aber kein Buchstabe?

weils so ist, weil der standard das nicht voesieht ... vermutlich sogar weil es einfacher ist eine begrenzte zahl interner variablen vozuhalten um damit mathematisch zu rechnen als dynamisch speicher für strings allokieren zu müssen und stringcompare routinen vorzuhalten ... frag die macher des c-standards

entschuldige meine offenheit aber deine verbohrtheit immer nur mundgerechte häppchen zu verlangen macht es sehr schwer sachlich mit dir zu reden

HaWe
11.12.2017, 13:45
ok, wenns absolut nicht ginge, wäre es ja ok -
aber in deinem Link schreibt doch einer, dass es doch ginge mit Buchstaben wie 'Q'?
https://stackoverflow.com/questions/2335888/how-to-compare-strings-in-c-conditional-preprocessor-directives


The answere by Patrick and by Jesse Chisholm made me do the following:

#define QUEEN 'Q'
#define JACK 'J'

#define CHECK_QUEEN(s) (s==QUEEN?1:0)
#define CHECK_JACK(s) (s==JACK?1:0)

#define USER 'Q'

[... later on in code ...]

#if CHECK_QUEEN(USER)
compile_queen_func();
#elif CHECK_JACK(USER)
compile_jack_func();
#elif
#error "unknown user"
#endif

Instead of #define USER 'Q' #define USER QUEEN should also work but was not tested also works and might be easier to handle.


das ist das, was ich hasse, wenn man Diskussionslinks als Antwort auf eine Frage gibt - da antworten dann 100 Leute mit 200 verschiedenen Meinungen....

(und so kompliziert wie dort ist es ja gar nicht mal bei mir)

Ceos
11.12.2017, 13:46
deswegen sollte man sich auf die lösung mit dem grünen haken fixieren das ist dann in 99% der fälle die lösung die jeder akzeptiert

wenn du 'Q' schreibst besteht der hauch einer chance dass der precompiler das vorher intern in seine ascii zahl "81" umwandelt, das ist aber keinenfalls standard und funktioniert vermutlich nur mit den allerwenigstens compilern

es geht jedenfalls nicht bis hin zu C11 bzw. C2011 compilern, danach schien der standard wohl neue möglichkeiten zu bieten


(und so kompliziert wie dort ist es ja gar nicht mal bei mir)

die ursprüngliche frage deckt sich exakt mit deiner .. nur ein wenig anders formuliert, schade dass du das so nciht erkennst ... wo wir wieder beim thema "über den tellerrand gucken" wären

HaWe
11.12.2017, 13:48
achso, der zitierte Code geht gar nicht bei Arduino C++, weil es nicht standardmäßig bereits C++11 ist? Ist das der Grund?
(was ist ein grüner Haken?)

Ceos
11.12.2017, 13:48
bis hin zu C11 bedeutet C11 eingeschlossen ... alles danach ist wohl intelligenter aber auch komplizierter zu nutzen

arduino standard meines wissens nach ist c99 also c1999

HaWe
11.12.2017, 14:01
deswegen sollte man sich auf die lösung mit dem grünen haken fixieren das ist dann in 99% der fälle die lösung die jeder akzeptiert

wenn du 'Q' schreibst besteht der hauch einer chance dass der precompiler das vorher intern in seine ascii zahl "81" umwandelt, das ist aber keinenfalls standard und funktioniert vermutlich nur mit den allerwenigstens compilern
...
die ursprüngliche frage deckt sich exakt mit deiner .. nur ein wenig anders formuliert, schade dass du das so nciht erkennst ... wo wir wieder beim thema "über den tellerrand gucken" wären

nein, die ursprüngliche Frage deckt sich absolut NICHT mit meiner, weil dort MULTIPLE VARIABLE ZeichenKETTEN verwendet und verglichen werden und nicht 1 Makroname mit einem einfachen konstanten Einzel-Zeichen!! Zeichen aber sollen ja FUNKTIONIEREN !
https://stackoverflow.com/questions/2335888/how-to-compare-strings-in-c-conditional-preprocessor-directives


How to compare strings in C conditional preprocessor-directives
I have to do something like this in C.
It works only if I use a char, but I need a string. How can I do this? // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


#define USER "jack" // jack or queen
#if USER == "jack"
#define USER_VS "queen"
#elif USER == "queen"
#define USER_VS "jack"
#endif

Ceos
11.12.2017, 14:04
(was ist ein grüner Haken?)

in kombination mit deinem letzten post bleibt mir da nur zu sagen


ich bin raus, viel spaß den andern :)

wenn du magst lösch ich noch meine beiträge dann hast du eine saubere diskussionsgrundlage mit anderen

HaWe
11.12.2017, 14:08
keine Ahnung, welche Laus dir jetzt schon wieder über die Leber gelaufen ist, schließlich bist du ja der, der nicht auf meine Frage exakt geantwortet hast, sondern mit unverständlichen Beispielen und irreführenden Links geantwortet hast.

Also noch mal die Ausgangsfrage vom TOP:


hallo,
ich möchte per bedingter Compilierierung meinen Code für verschiedene Zielplattformen anpassen, ähnlich wie hier:


#define TARGET 3 // willkürlicher Wert je nach Zielplattform
#if TARGET==1
/* code wenn TARGET gleich 1 ist */
#elif TARGET==2
/* code wenn TARGET 2 ist */
#else
/* code wenn TARGET nicht 1 oder 2 ist*/
#endif

Der Wert der Konstanten für TARGET muss global im Kopf deklariert werden, also außerhalb von Funktionen.
Daneben müsen die #if / #elif -Abfrage ebenfalls im Kopf möglich sein (für weitere globale #define-Konstanten, die sich daraus ergeben), zusätzlich aber auch im Code selber.
- das geht mit den Zahlen-Konstanten auch soweit.

A-Bär:
meine Werte für TARGET sind nicht numerisch, sondern Buchstaben (U, M, Z, D oder E) -
wie muss ich dann TARGET #definieren? und wie lauten dann die zugehörigen #if / #elif Abfragen?
#define TARGET Z
#if TARGET==Z // ???
#if TARGET=='Z' // ???

oder
#define TARGET 'Z'
#if TARGET==Z // ???
#if TARGET=='Z' // ???

oder
const char TARGET = 'Z';

und wie lauten dann die zugehörigen #if / #elif Abfragen?

oder geht das gar nicht mit Buchstaben oder C strings?

Ceos
11.12.2017, 14:11
schließlich bist du ja der, der nicht auf meine Frage exakt geantwortet hast ... unverständlichen Beispielen und irreführenden Links

träum weiter :D ganz einfach

ich hätte aussagen wie "verwirrend" statt "irreführend" und "für mich unverständliche links" hingenommen, aber deine unbekümmerte art ohne nachdenken einfach zu plappern und leute vor den kopf zu stoßen ist einfach unverkennbar und macht eben deine persönlichkeit aus, mein angebot die postings im friedlichen zu löschen kannste dir an die backe kleben

HaWe
11.12.2017, 14:58
träum weiter :D ganz einfach

das war als Beginn einer neuen Diskussion gedacht, eventuell weiß ja jemand - außer dir - ob es ggf doch geht, und wenn, wie genau.

Also noch mal die Ausgangsfrage vom TOP....


- - - Aktualisiert - - -

Update:
also, es funktioniert DOCH, irgendwie war beim Umstecken der Boards und Ändern der neuen dazu passenden #defines wohl Fehler passiert.
Aber so geht es


#define TARGET 'D'

#if TARGET=='Z'
// Code Z
#elif TARGET=='E'
// Code E
#elif TARGET=='D'
// Code D
#else
// Code default
#endif

Ceos
11.12.2017, 15:10
das hatte ich sogar erwähnt gehabt dass es compiler gibt die implizit einzelzeichen in ihren ascii wert umwandeln 'Q' = 81

teste es einfach mal indem du folgenden code schreibst

#define TARGET 'Q'

#if (TARGET==81)

sollte ebenfalls TRUE ergeben

ist dennoch nicht standard sondern eine zugabe des spezifischen compilers

HaWe
11.12.2017, 15:13
@ceos:
dein Post

in kombination mit deinem letzten post bleibt mir da nur zu sagen
ich bin raus, viel spaß den andern :)
wenn du magst lösch ich noch meine beiträge dann hast du eine saubere diskussionsgrundlage mit anderen
kam VOR meinem, in dem ich geantwortet habe:

keine Ahnung, welche Laus dir jetzt schon wieder über die Leber gelaufen ist, schließlich bist du ja der, der nicht auf meine Frage exakt geantwortet hast, sondern mit unverständlichen Beispielen und irreführenden Links geantwortet hast.

und du hast ja auf den Link verwiesen, um zu beweisen, dass es angeblich nicht geht

die ursprüngliche frage deckt sich exakt mit deiner .. nur ein wenig anders formuliert, schade dass du das so nciht erkennst ... wo wir wieder beim thema "über den tellerrand gucken" wären

FAZIT (damit kannst du das Thema als erledigt markieren): Es geht nicht, der Precompiler kann nur mit Zahlen arbeiten

wenn es doch zu kompliziert klingt, akzeptiere bitte meine antwort: "Es geht nicht!" ... ich habe dieses mal sogar von anfang an referenzen serviert um es zu belegen!

Andererseits dreht sich das dortige Topic gar nicht um char, sondern um strings, und es sagt doch der OP des dortigen Topics eindeutig:

It works only if I use a char, but I need a string. How can I do this?
Auch in andere Posts dort verwenden manche chars.
Was also soll da nicht irreführend sein?

Tatsächlich aber geht es ja nun doch, s.o.

Ceos
11.12.2017, 15:18
irreführung setzt einen vorsatz voraus andere in die irre führen zu wollen ... ergo eine unterstellung


es sind die unüberlegten unterstellungen die mich an deiner ausdrucksweise zur weißglut treiben

HaWe
11.12.2017, 16:28
irreführung setzt einen vorsatz voraus andere in die irre führen zu wollen ... ergo eine unterstellung
es sind die unüberlegten unterstellungen die mich an deiner ausdrucksweise zur weißglut treiben

nein, irreführend heißt einfach nur: irreführend = in die Irre führend, genau so wie verwirrend einfach nur ver_wirr_end = wirr-machend heißt, und genau das ist es, was passiert ist.
Irren kann sich jeder, keine Frage.
Ob vorsätzlich oder fahrlässig oder zufällig, ist eine ganz andere Kategorie, und dass Leute hier vorsätzlich andere Leute irreführen, habe ich dir oder anderen mit keinem Wort unterstellt
- nur die Aussage in deinen Posts haben mich eben sehr wohl verwirrt und in die Irre geführt, da sie völlig widersprüchlich waren zu dem, was in deinem eigenen Link ausgeführt wurde.
Und wie gesagt, meine Bemerkung kam erst als Antwort, nachdem du bereits verbal die Klamotten hingeschmissen hattest - daher meine Frage dann nach der "Laus" und meine Bemerkung zu "irreführend" etc.

PS,
jetzt habe ich auch endlich den "grünen Haken" in deinem Link unter der "50" gefunden - so einer ist mir noch nie zuvor aufgefallen , und außerdem hat diese "Lösung" ja auch überhaupt nichts mit meiner Frage zu tun: denn insb. hier kommt ja kein einziger Char vor, wie ich ihn bei mir gebraucht hätte.

Holomino
11.12.2017, 18:51
Gibt's jetzt auch noch "magic chars"?
Ich vermute mal 'Z' steht für Zero, ist 'W' dann ZeroW?

HaWe
11.12.2017, 19:18
Gibt's jetzt auch noch "magic chars"?
Ich vermute mal 'Z' steht für Zero, ist 'W' dann ZeroW?
die, die ich oben ursprünglich verwendet habe, waren für die Boards U_no, M_ega, Z_ero, D_ue, E_SP8266, manchmal waren es auch nur willkürliche Buchstaben zu debug-Testzwecken für println() oder auch für ganz andere Zwecke.