Gast
#6650913
Guten Morgen,
1 | |
2 | |
3 | |
4 | |
ich würde gerne Strukturen Namen mittels defines erstellen. Klappt so nicht, geht das überhaupt? Kommt immer structXType_APPENDIX raus oder es lässt sich nicht kompilieren. GCC
|
Anzeige
|
struct Name mittels define erstellen - gcc
Gast
#6650913
Guten Morgen,
ich würde gerne Strukturen Namen mittels defines erstellen. Klappt so nicht, geht das überhaupt? Kommt immer structXType_APPENDIX raus oder es lässt sich nicht kompilieren. GCC
Mike schrieb: > #define APPENDIX "xyz" > typedef struct{ > short var; > }structXType_(APPENDIX); Das würde "}structXType_("xyz");" ergeben. Wenn überhaupt dann eher so:
Am ende ist das ganze ein simples suchen und ersetzen von Text. Zusammenfügen von Variabelnname geht nur innerhalb des Macros:
Gast
#6650935
Yalu X. schrieb: > ## kenn ich aber kann ich wohl nicht richtig einsetzen:
geht nämlich auch nicht
Gast
#6650945
Irgend W. schrieb: > #define OwnStruct(a) \ > struct{ \ > short var; \ > }structXType_##a; > OwnStruct(xyz); Danke das klappt aber hab da wohl etwas zu stark verkürzt hätte nämlich in der struktur nochmal ein define das geht dann nicht
error: '#' is not followed by a macro parameter Und nachdem ich da ganze viele verschiedene ifdef Varianten nochmal hab kann ich das auch nicht rausnehmen.. An sich sollte die Struktur wo definiert sein und mit config files kann man verschiedene typen der Struktur vor dem kompilieren anlegen. Präprozessordirektiven wie #ifdef, #endif usw. sind innerhalb einer makrodefinition nicht erlaubt. Vielleicht solltest du mal etwas weiter ausholen und dein Problem als Ganzes beschreiben.
Gast
#6651029
Mike schrieb: > An sich sollte die Struktur wo definiert sein und mit config files kann > man verschiedene typen der Struktur vor dem kompilieren anlegen.
führt aber ins Chaos. Keine Sau kann das lesen. Für sowas nehme ich Textfresser (z.B. awk) und mache aus einer config datei entsprechenden C-Code (.h/.c). Vorteil: Du hast am Ende plain C-Code, für Dich, Deinen Debugger, Deine IDE, ...
Gast
#6651306
aus dem Kochstudio: auch CMake kann Configurations Dateien aus Templates anlegen und Texte ersetzen https://cmake.org/cmake/help/v3.18/command/configure_file.html
Gast
#6651340
> >geht nämlich auch nicht Dann lass die Anführungsstriche weg. Mike schrieb: > ich würde gerne Strukturen Namen mittels defines erstellen. Klappt so > nicht, geht das überhaupt? Das geht bestimmt, aber man tut das nicht. Der gcc versucht nur, dich schonend auf den rechten Weg zu führen.
Gast
#6651989
Bauform B. schrieb: > Das geht bestimmt, aber man tut das nicht. Der gcc versucht nur, dich > schonend auf den rechten Weg zu führen. Das tut man schon und das ist manchmal auch ein richtiger Weg. *Beispiel in c++*
Das Makro erstellt eine Register-Klasse für den Zugriff auf auf die Hardware -Register z.B. für die Timer von ATtiny-261-461-861 wie im Anhang beschrieben. Was den Kommentar Bauform B. schrieb: > Das geht bestimmt, aber man tut das nicht. Der gcc versucht nur, dich > schonend auf den rechten Weg zu führen. äußerst eindrücklich unterstreicht. Oliver Mitleserin (a.b.) schrieb: > Das tut man schon Aber sehr selten. > und das ist manchmal auch ein richtiger Weg. Noch seltener. Ich würde für dein Beispiel einen kleinen Codegenerator mit z.B. Python schreiben. Der könnte dann z.B. auch gleich noch automatisch die XML-Beschreibungen der I/O-Register einlesen und verarbeiten. Hallo, was soll das denn überhaupt werden? Mir ist das noch zu kurz beschrieben. Generell sollte man defines meiden wenn immer es möglich ist. Warum soll ein struct überhaupt define abhängig sein? Vor allem, warum will man a) Ein C++-Template durch ein #define-Makro nachbauen b) überhaupt die Registerzugriffe über Funktionen machen c) die für alle möglichen Typen per einfachem cast. Wer braucht z.B.
Oliver
Gast
#6652691
Veit D. schrieb: > Generell sollte man defines meiden wenn immer es möglich ist. Das ist nicht ganz richtig. Solange es lesbar (und das heisst auch: per Textsuche auffindbar) ist, spricht nichts dagegen. Als Konfiguration (in C) sind defines ein relativ gut standardisiertes und nutzbares Format. Vor allem, weil man daraus ganz gute C-Fresser (in analogie zu Textfressern) bauen kann. Was nur unbedingt vermieden werden sollte, ist das erstellen oder nutzen von Token, die nicht im Klartext vorliegen. Also genau das, was der TO machen will. Also ein MAX_CURRENT, WITH_ABC oder #define draw() drawLcd1455() sind ok. Ein "int abc(def);", dass zum "int abc_def;" wird (oder noch abgefahrener), nicht. Zumindest wenn dessen Scope mehr als ein paar Zeilen umfasst.
Gast
#6653142
Guten Morgen, ok dann bau ich einen Generator. Danke für die Meinungen.
Gast
#6653190
Mike schrieb: > ok dann bau ich einen Generator. Eben, da du deine varianten auch steuern musst, wird sowas am besten im Make mit integriert. und CMake könnte die Dateien erzeugen ....
Gast
#6653226
Kochstudio schrieb: > Eben, da du deine varianten auch steuern musst, wird sowas am besten im > Make mit integriert. und CMake könnte die Dateien erzeugen . Nun leg doch nicht sofort noch Mühlsteine oben drauf: Zuerst den Generator. In der für ihn einfachsten Sprache. Und den immer besser. Und dann, falls mehr als einmal im Monat gebraucht, in cmake, wenn er cmake verwendet. Oder sein make. Oder seine Batchdatei. Aber das ist Kür. Guten C sourcecode zu erstellen.isthier Pflicht
Gast
#6653244
Mike schrieb: > ok dann bau ich einen Generator. Danke für die Meinungen. Da kann ich auch noch eine Meinung beisteuern: Wenns mit Makros nicht zu kompliziert ist (es wurde ja schon festgestellt, dass du nur zu viele Anführungszeichen hattest), dann nimm Makros statt eines Generators. Den Generator musst du nämlich auch pflegen. Und wenn sich der generierte Code häufig ändert (sonst könntest du es ja gleich von Hand schreiben), ins build-system (make oder cmake?) einbinden. Und dieses build-System dann auch noch pflegen. Und für den Generator musst du noch einen Compiler oder Interpreter mit pflegen (den du, falls aller andere Code cross-compiliert ist, nicht selbstverständlich hast).
Gast
#6653272
Sebastian schrieb: > dann nimm Makros statt eines Generators Das Problem ist, dass die Objekte nicht lesbar sind. Du hast ein sObjektABC und keine Möglichkeit, die Definition oder Deklaration zu finden. Und nicht nur Du: auch der Debugger, die IDE, ... . Prinzipiell sind die Infos im Klartext da, wenn man das ganze durch den präprozessor jagt, nur fehlt dann z.b. jeder Kommentar. Sebastian schrieb: > Mike schrieb: >> ok dann bau ich einen Generator. Danke für die Meinungen. > > Da kann ich auch noch eine Meinung beisteuern: Wenns mit Makros nicht zu > kompliziert ist (es wurde ja schon festgestellt, dass du nur zu viele > Anführungszeichen hattest), dann nimm Makros statt eines Generators. Meine Aussage wäre inhaltlich zwar ähnlich (einfach->Makro, kompliziert->Generator), aber ich würd's gerade umgekehrt sagen: Wenn es mit Makros nicht sehr einfach ist, bau dir stattdessen einen Generator. Vor allem ist hier, wie schon von anderen angemerkt, das Problem, dass Identifier per Makro zusammengebaut werden. > Den Generator musst du nämlich auch pflegen. Und wenn sich der > generierte Code häufig ändert (sonst könntest du es ja gleich von Hand > schreiben), ins build-system (make oder cmake?) einbinden. > Und dieses build-System dann auch noch pflegen. Das ist in der Regel aber nicht besonders schwer. Muss man halt einmal rausfinden, wie das geht, und danach kann man das immer wieder verwenden. > Und für den Generator musst du noch einen Compiler oder Interpreter mit > pflegen (den du, falls aller andere Code cross-compiliert ist, nicht > selbstverständlich hast). Ich finde, wer ernsthaft programmiert, sollte sowieso zumindest eine Skriptsprache einigermaßen können und dann natürlich auch den Interpreter dafür bereits installiert haben. Im Falle von Python und Linux (das ist in meinem Fall die Wahl) ist das sowieso schon vorinstalliert. Mit so einer Skriptsprache kann man einerseits solche Generatoren, andererseits auch mal ein kleines "wegwerf-Skript" basteln, um schnell irgendwas auszuprobieren oder etwas zu erzeugen, das man gerade braucht. Ich mache das zumindest öfters. A. S. schrieb: > Veit D. schrieb: >> Generell sollte man defines meiden wenn immer es möglich ist. > Das ist nicht ganz richtig. Solange es lesbar (und das heisst auch: per > Textsuche auffindbar) ... Hallo, es ist nicht die Frage ob richtig oder falsch. Die Frage lautet was ist besser oder weniger besser. Was ist sicherer oder weniger sicherer. Ich bin da eben anderer Meinung. defines kann man doppelt und dreifach definieren. Das Letzte define gewinnt. Ich habe das schon vertreut im Code gesehen wo sich jemand wunderte das es nicht richtig tut. Maximal kommt eine redefine Warnung (kein Fehler), falls nicht unterdrückt. Ich weiß das C Programmierer ihre defines lieben und man kann damit sicherlich sehr viel machen. Aber man kann damit auch sehr viel Mist machen. Bspw. bei falscher Klammersetzung. Veit D. schrieb: > Maximal kommt eine redefine Warnung (kein Fehler), falls nicht > unterdrückt. Wer Warnungen unterdrückt oder ignoriert, hat die daraus entstehenden Probleme verdient.
Gast
#6653347
Veit D. schrieb: > Ich bin da eben anderer Meinung. Eine andere Meinung ist ja OK. Doch sind rationale Argumente einfacher zu diskutieren. > defines kann man doppelt und dreifach definieren. Das Letzte define gewinnt. Ich habe das schon [...] gesehen Das ist m.E. kein Argument. Einen etablierten Mechanismus nicht zu nutzen, weil andere damit Unsinn machen, hieße auf C in Gänze zu verzichten. Wenn Du hingegen ein Beispiel hast, dass mit Methode XY besser geht als mit #define: Nur zu. Die fehlenden Identifier z.B. sind ein Argument. Hallo, die alles oder nichts Argumentation gefällt mir nicht. Wenn man defines in C reduziert wo es möglich ist, wäre schon viel gewonnen. Zum Bsp. Konstanten als Konstanten zu schreiben und nicht mit define. Eine define "Formel" kann man auch als Funktion schreiben. Das alles heißt noch lange nicht das man auf sein C verzichten muss.
Gast
#6653419
Veit D. schrieb: > Zum Bsp. Konstanten als Konstanten zu schreiben und nicht mit define. Wie genau macht man das? Willst du in jede C-Datei wo Pi gebraucht wird ein
schreiben?
> Eine define "Formel" kann man auch als Funktion schreiben.
Auch hier ist die Frage, wie du erreichen willst, dass die Funktion die
gleichen (guten) Eigenschaften hat wie das Makro?
Veit D. schrieb: > die alles oder nichts Argumentation gefällt mir nicht. Wenn man defines > in C reduziert wo es möglich ist, wäre schon viel gewonnen. Zum Bsp. > Konstanten als Konstanten zu schreiben und nicht mit define. Es gibt in C keine Konstanten außer die, die direkt als Wert hingeschrieben werden. Deshalb nimmt man dafür ja define. Ich sehe auch kein Problem darin, dafür #define zu benutzen. > Eine define "Formel" kann man auch als Funktion schreiben. Oft ja, und mit inlining bekommt man genau so optimierten Code. mh schrieb: > Veit D. schrieb: >> Zum Bsp. Konstanten als Konstanten zu schreiben und nicht mit define. > Wie genau macht man das? Willst du in jede C-Datei wo Pi gebraucht wird > einstatic const double pi = 3.1413331233; > schreiben? Man könnte es in den Header schreiben, genau wie das entsprechende #define auch. >> Eine define "Formel" kann man auch als Funktion schreiben. > Auch hier ist die Frage, wie du erreichen willst, dass die Funktion die > gleichen (guten) Eigenschaften hat wie das Makro? Welches Problem siehst du? Ich sehe nur eins mit so Dingen wie
weil man daraus für jeden Datentyp eine eigene Funktion machen müsste, mit eigenem Namen. Aber Veit schreibt ja, dass es für ihn nicht um "alles oder nichts" geht. Er möchte Makros möglichst vermeiden, nicht komplett abschaffen.
Gast
#6653437
Veit D. schrieb: > Zum Bsp. Konstanten als Konstanten zu schreiben und nicht mit define. > Eine define "Formel" kann man auch als Funktion schreiben. Das alles > heißt noch lange nicht das man auf sein C verzichten muss. Das geht in C++. In C ist das oft Overkill, Dummheit oder gar unmöglich, keine defines zu nehmen. Ein Makro hat ganz andere Eigenschaften als eine Funktion. Wenn Du kein C magst oder brauchst, dann ist das OK. Aber Hunde als Haustiere abzulehnen, weil Schlitten von Rentieren gezogen werden können, wird niemandem gerecht.
Gast
#6653467
Rolf M. schrieb: > Man könnte es in den Header schreiben, genau wie das entsprechende > #define auch. Nur hat man den Wert dann evtl. mehrfach im RAM und ROM. Rolf M. schrieb: > Welches Problem siehst du? Ich sehe nur eins mit so Dingen wie#define > MAX(a, b) ((a) > (b) ? (a) : (b)) > weil man daraus für jeden Datentyp eine eigene Funktion machen müsste, > mit eigenem Namen. Wenn man die Funktion nicht mit static inline in nen header packt, muss man für den Funktionsaufruf zahlen. Rolf M. schrieb: > Aber Veit schreibt ja, dass es für ihn nicht um > "alles oder nichts" geht. Er möchte Makros möglichst vermeiden, nicht > komplett abschaffen. Und als Beispiel dafür wählt er zwei Beispiele, ohne zu sagen, wann und wie man das machen kann.
Gast
#6653494
Rolf M. schrieb: > Welches Problem siehst du? Alles wo # oder ## drin vorkommt. Alles was im präprozessor passieren muss. Alles wo 2 token zu einem verschmelzen sollen, ohne ein eigenes Objekt zu erschaffen. mh schrieb: > Rolf M. schrieb: >> Man könnte es in den Header schreiben, genau wie das entsprechende >> #define auch. > Nur hat man den Wert dann evtl. mehrfach im RAM und ROM. Kommt auf das Optimierungsverhalten des Compilers an. Und bei #define hat man das Problem auch. Die Problematik mit const ist eher, dass man es nicht überall einsetzen kann, wo ein #define ginge, weil es eben nur eine Variable ist, die sich nicht ändert und kein konstanter Ausdruck, wie es in C++ wäre. Auf https://en.cppreference.com/w/c/language/const ist es ganz gut zusammengefasst: "C adopted the const qualifier from C++, but unlike in C++, expressions of const-qualified type in C are not constant expressions; they may not be used as case labels or to initialize static and thread storage duration objects, enumerators, or bit field sizes. When they are used as array sizes, the resulting arrays are VLAs." > Wenn man die Funktion nicht mit static inline in nen header packt, muss > man für den Funktionsaufruf zahlen. Ja, also wenn man sie nicht dorthin schreibt, wo auch das Makro stehen müsste. Aber seit LTO gilt das auch nicht mehr unbedingt. Mit einem sogenannten X-Macro sollte es gehen ...
Hallo, Rolf hat mich verstanden. Es geht um Code den man selbst schreibt. Aber ich bin kein Missionar, wollte es nur mal erwähnt haben. Bsp., nur die assert Meldung bekomme ich nicht hin, dass ginge in C++ mit static_assert ganz einfach.
Gast
#6654528
Veit D. schrieb: > Es geht um Code den man selbst schreibt. Natürlich. Auf anderen hat man wenig Einfluss. > Bsp., nur die assert Meldung bekomme ich nicht hin, dass ginge in C++ > mit static_assert ganz einfach. Je nach Compiler mit 0, -1 oder einfach nur anders
Und klar, natürlich ist es sinnlos, für die Baudrate ein #define zu nehmen, wenn Du es direkt in Code schreiben kannst. Das hat aber nichts mit #define vs Funktion zu tun. Und natürlich ist es auch sinnlos, ein #define zu nehmen, wenn man stattdessen eine inline-Funktion nehmen kann. Das wäre so sinnfrei, wie a+a+a+a+a+a statt 6*a um die Multiplikation zu sparen.
Gast
#6654531
Veit D. schrieb: > Bsp., nur die assert Meldung bekomme ich nicht hin, dass ginge in C++ > mit static_assert ganz einfach. Veit D. schrieb: > Hallo, > > Rolf hat mich verstanden. > Es geht um Code den man selbst schreibt. Aber ich bin kein Missionar, > wollte es nur mal erwähnt haben. > [...] Was genau soll der Quelltext zeigen? Wenn ich mir das fehlende
hinzufüge, produziert der Compiler nen haufen Code (350 Zeilen + calls in die Floatingpoint-Lib), der zur Laufzeit ausgeführt werden muss. Veit D. schrieb: > Bsp., nur die assert Meldung bekomme ich nicht hin, dass ginge in C++ > mit static_assert ganz einfach. Ja das geht in C++ ganz einfach, dafür muss man allerdings erstmal den ganzen anderen Kram richtig machen.
Gast
#6654535
mh schrieb: > (350 Zeilen + calls in die Floatingpoint-Lib) Sorry, es sind nur 160 Zeilen + float, hab das -Os verschluckt. Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|