Guten Tag!
Ich habe ein C-Projekt, bestehend aus main.c und uart.h bzw der
entsprechenden c-Datei. Nun habe ich folgendes Konstrukt:
In uart.h steht unter anderem folgendes:
[c]
/** Size of the circular receive buffer, must be power of 2 */
#ifndef UART_RX_BUFFER_SIZE
#define UART_RX_BUFFER_SIZE 32
#endif
/** Size of the circular transmit buffer, must be power of 2 */
#ifndef UART_TX_BUFFER_SIZE
#define UART_TX_BUFFER_SIZE 32
#endif
[\c]
Und in meiner main.c:
[c]
#define UART_RX_BUFFER_SIZE 64 // Size of the circular receive buffer,
must be power of 2
#define UART_TX_BUFFER_SIZE 64 // Size of the circular transmit buffer,
must be power of 2
[\c]
Eigentlich möchte ich die uart.h unberührt lassen und besagtes define in
main.c auslagern. Leider kommt dabei ein redefinition-error, wenn ich
#include "uart.h" vor dem define im main-file setze. Einzige Möglichkeit
die ich bisher sehe ist das include unter das define zu setzen, was aber
doch irgendwie unschön ist... so ein include gehört doch als erstes in
main.c... Irgendeine Idee, das zu bewerkstelligen?
EDIT: Irgendwie krieg ich das mit dem [c]...[\c] formatieren nicht
hin...
Viele Grüße,
Stefan
Hallo,
genauso wie Du es machst, ist es die einzige Möglichkeit. Ein
redefinieren der defines geht in diesem fall nur so.
Vorausgesetzt, Du willst die uart.h nicht verändern. Ich stelle mir nur
die Frage, warum willst Du die uart.h nicht verändern?
Gruß
Frank
[edit] Alternativ, kannst Du ein #undef verwenden.
Nach dem #include "uart.h"
machst Du ein #undef auf die beiden defines und deklarierst Deine
eigenen. Das funktioniert aber nur, wenn auf die beiden defines nicht
innerhalb der uart.h zugegriffen wird.
Stefan S. schrieb:> Einzige Möglichkeit> die ich bisher sehe ist das include unter das define zu setzen, was aber> doch irgendwie unschön ist...
Ich sehe nicht, was daran "unschön" sein soll, insbesondere wenn man es
entsprechend zusammenfasst, so dass der Zusammenhang offensichtlich
wird:
Frank Link schrieb:> Vorausgesetzt, Du willst die uart.h nicht verändern. Ich stelle mir nur> die Frage, warum willst Du die uart.h nicht verändern?
Weil eine Headerdatei nicht dazu da ist, ständig editiert zu werden?
Da gehören Sachen rein, die einfach nur verwendet werden.
Sonst könnte man ihren Inhalt auch gleich in die .c reinmatschen.
Daß es hier oft anders gehandhabt wird, ist ein anderes Thema - steht
aber dem nachvollziehbaren Wunsch nicht entgegen, eine Headerdatei
unangetastet zu lassen.
Nachdem darin ja bereits mit einem #ifdef... vorgesehen ist, auf
selbstdefinierte Größen sinnvoll zu reagieren, macht es auch gar keinen
Sinn, darin zu ändern.
Das Ganze wird aber so (ohne Verändern der uart.h) gar nicht
funktionieren, denn der Code in uart.c wird ja so mit den falschen
(originalen) Defines arbeiten.
Wieso?
Man definiert sich seine Wunschwerte vor dem #include, in der
Headerdatei wird mit #ifndef UART_RX_BUFFER_SIZE... festgestellt, daß es
den Wert schon gibt und nicht umdefiniert.
So arbeiten die Headerdatei und main.c mit demselben Wert.
Nach dem #include geht es in main.c mit den richtigen Werten weiter.
Oder habe ich etwas übersehen?
Vielen Dank für die Antworten!
Ich habe eben ausprobiert was passiert, wenn ich das define in main.c
vor das include setze. (Habe einfach in ein #warning in das #ifndef
gesetzt und siehe da, es kommt keine warning, wenn ich das define vor
das include setze).
Gruß,
Stefan
Klaus Wachtler schrieb:> So arbeiten die Headerdatei und main.c mit demselben Wert.> Nach dem #include geht es in main.c mit den richtigen Werten weiter.>> Oder habe ich etwas übersehen?
Ja, den Code in uart.c.
Stefan Ernst schrieb:> Das Ganze wird aber so (ohne Verändern der uart.h) gar nicht> funktionieren, denn der Code in uart.c wird ja so mit den falschen> (originalen) Defines arbeiten.
Jede Wette, dass er den Code nicht in einer uart.c sondern komplett in
uart.h hat.
Hmm... so einfach wars anscheinend doch nicht. Ich habe nun die defines
aus uart.h auskommentiert und nur in main.c definiert und schon kommt
ein undeclared-error.
Komme ich nicht drum herum, die defines in uart.h zu ändern? Es ist
doof, wenn ich nicht in main.c die Puffergröße ändern kann, sondern
immer die uart.h verändern muss. Sowas wie "globale defines" gibts
anscheinend nicht (also ein define, das in main geschrrieben wird und
ebenfalls in uart.c benutzt werden kann. Wahrscheinlich liegt das daran,
dass uart.c erst einzeln kompiliert wird?!)
Ich nutze die uart.c und uart.h von Peter Fleury für einen ATmega8.
Stefan S. schrieb:> immer die uart.h verändern muss. Sowas wie "globale defines" gibts> anscheinend nicht
so direkt nicht.
Aber praktisch alle Compiler erlauben es, dass man ihnen auf der
Command-Line Belegungen für einige #define mitgeben kann.
Dort (in der Projektverwaltung bzw. im Makefile) ist also der Platz wie
man solche Dinge realisiert. Damit ist dann auch gewährleistet, dass
alle C-Files, die zum Projekt gehören, mit identischen #define-Werten
compiliert werden.
> ebenfalls in uart.c benutzt werden kann. Wahrscheinlich liegt das daran,> dass uart.c erst einzeln kompiliert wird?!)
Bingo.
Daher würde es dir auch nichts bringen, wenn du in main.c andere Werte
als in uart.c hast. Denn noch schlimmer als ein Header File ändern zu
müssen ist es, wenn unterschiedliche C-Files mit essentiell wichtigen
Konstanten unterschiedlich compiliert werden.
Stefan S. schrieb:> Komme ich nicht drum herum, die defines in uart.h zu ändern? Es ist> doof, wenn ich nicht in main.c die Puffergröße ändern kann, sondern> immer die uart.h verändern muss.
Warum?
> Sowas wie "globale defines" gibts anscheinend nicht (also ein define, das> in main geschrrieben wird und ebenfalls in uart.c benutzt werden kann.
Genau dafür ist doch das define in uart.h da. Wenn du in main.c die
Sachen nochmal definierst, hast du eine Definition nur für main.c und
dann noch in uart.h eine "globale" für alles andere.
Stefan S. schrieb:> Und in meiner main.c:
Wenn die Defines schon bestehen, etwa weil uart.h bereits includet wurde
oder die Defines auf der Kommandozeile geschehen, dann überschreibt man
die Makros mit:
1
#undef UART_RX_BUFFER_SIZE
2
#define UART_RX_BUFFER_SIZE 64 // Size of the circular receive buffer,
Damit wird zudem ersichtlich, daß es woanders eine
Default-Initialisierung gibt.
Rolf Magnus schrieb:> Stefan S. schrieb:>> Komme ich nicht drum herum, die defines in uart.h zu ändern? Es ist>> doof, wenn ich nicht in main.c die Puffergröße ändern kann, sondern>> immer die uart.h verändern muss.>> Warum?
Weil ich gerne am Ende ein Programm vorliegen haben möchte, in dem ich
alle "Einstellungen" zentral in main.c treffen kann. Annahme: Nach einem
Jahr schaue ich mir das Programm mal wieder an, dann wäre es
schrecklich, erst in allen Dateien nach Definitionen zu suchen...
Karl Heinz Buchegger schrieb:>> immer die uart.h verändern muss. Sowas wie "globale defines" gibts>> anscheinend nicht>> so direkt nicht.> Aber praktisch alle Compiler erlauben es, dass man ihnen auf der> Command-Line Belegungen für einige #define mitgeben kann.> Dort (in der Projektverwaltung bzw. im Makefile) ist also der Platz wie> man solche Dinge realisiert. Damit ist dann auch gewährleistet, dass> alle C-Files, die zum Projekt gehören, mit identischen #define-Werten> compiliert werden.
Vielen Dank für diesen heißen Tipp :-) Habe die Command-line Optionen in
AVR Studio 5 gefunden und er kompiliert das Projekt (sowohl main.c, als
auch uart.c) ohne Probleme!
Stefan S. schrieb:> Rolf Magnus schrieb:>> Stefan S. schrieb:>>> Komme ich nicht drum herum, die defines in uart.h zu ändern? Es ist>>> doof, wenn ich nicht in main.c die Puffergröße ändern kann, sondern>>> immer die uart.h verändern muss.>>>> Warum?> Weil ich gerne am Ende ein Programm vorliegen haben möchte, in dem ich> alle "Einstellungen" zentral in main.c treffen kann. Annahme: Nach einem> Jahr schaue ich mir das Programm mal wieder an, dann wäre es> schrecklich, erst in allen Dateien nach Definitionen zu suchen...
Wieso suchen? Dein Programm besteht aus Modulen. Eins davon ist uart,
und da gibt es einen Heder, der alle uart-spezifischen Einstellungen
beinhaltet.
Oder, wenn dein Programm zu klein ist für so eine Einteilung, baue dir
einen Konfigurations-Header, in dem das alles drin steht. Wenn du deine
Einstellungen (in Form von #define) alle in main.c machst, kannst du die
nämlich auch nur in main.c verwenden.
Karl Heinz Buchegger schrieb:> Aber praktisch alle Compiler erlauben es, dass man ihnen auf der> Command-Line Belegungen für einige #define mitgeben kann.> Dort (in der Projektverwaltung bzw. im Makefile) ist also der Platz wie> man solche Dinge realisiert. Damit ist dann auch gewährleistet, dass> alle C-Files, die zum Projekt gehören, mit identischen #define-Werten> compiliert werden.
Nunja, für zwei oder drei defines finde ich das noch ok, aber wenn du
einen ganzen Stall davon hast, der dann kommentarlos irgendwo im
Makefile rumfährt und die Compiler-Kommandozeile unleserlicher macht,
ist das auch nicht unbedingt das gelbe vom Ei.
Rolf Magnus schrieb:> Oder, wenn dein Programm zu klein ist für so eine Einteilung, baue dir> einen Konfigurations-Header, in dem das alles drin steht. Wenn du deine> Einstellungen (in Form von #define) alle in main.c machst, kannst du die> nämlich auch nur in main.c verwenden.
Das hört sich natürlich auch gut an... du meinst eine config.h mit den
allgemein gültigen Einstellungen erstellen und die in alle anderen
header-Dateien einbinden?
Rolf Magnus schrieb:>> Dort (in der Projektverwaltung bzw. im Makefile) ist also der Platz wie>> man solche Dinge realisiert. Damit ist dann auch gewährleistet, dass>> alle C-Files, die zum Projekt gehören, mit identischen #define-Werten>> compiliert werden.>> Nunja, für zwei oder drei defines finde ich das noch ok, aber wenn du> einen ganzen Stall davon hast, der dann kommentarlos irgendwo im> Makefile rumfährt und die Compiler-Kommandozeile unleserlicher macht,> ist das auch nicht unbedingt das gelbe vom Ei.
Bin bei dir.
Unglücklicherweise (für mich), hab ich da nämlich auch noch keine gute
alternative Lösung dafür. Ein config.h klappt so nicht, weil ich zb die
uart.c, lcd.c auf eigenen Codelib-Subverzeichnissen halten möchte ohne
sie jeweils ins laufende Projektverzeichnis kopieren zu müssen. Nur von
dort geht ein #include aufs jeweilige Projektverzeichnis wieder nicht.
Das hat nichts mit global oder nicht zu tun, sondern damit dass
Präprozessoranweisungen sequentiell funktionieren... Das kann man auch
bewusst nutzen ala
#define BLUB 13
#define BLA 0815
#include "template.inc"
#undef BLA
#define BLA 42
#include "template.inc"
#undef BLA
#undef BLUB