Forum: Compiler & IDEs #if und #ifndef über mehrere Dateien


von Manuel F. (dobby)


Lesenswert?

Hallo.

Ich beschäftige mich seit geraumer Zeit mit C++ und bin mittlerweile 
dabei eine kleine Bibliothek selber zu erstellen. Mit dem Header 
schreiben und einbinden klappt problemlos. Nun bin ich allerdings auf 
ein Problem gestoßen für das ich trotz Recherche keine richtige Lösung 
finde.

Und zwar möchte ich mit dem Präprozessor zwei unterschiedliche Sätze an 
Konstanten (viel mehr Textersetzungen) durchführen. Dazu habe ich im 
Header OneWire.h folgenden Code stehen.
1
#ifndef OVERRIDE
2
   #define H 480      //Reset: time for drive bus low
3
   #define I 70       //Reset: time for release bus
4
   #define G 0        //Reset: delay before reset pulse
5
#else
6
   #define H 70       //Reset: time for drive bus low
7
   #define I 8.5      //Reset: time for release bus
8
   #define G 2.5      //Reset: delay before reset pulse
9
   # warning "bus in override mode"
10
#endif

Jetzt war die Idee in der main.cpp über
1
#define OVERRIDE
die Konstanten umzuschalten. Die Konstanten werden in der Datei 
OneWire.cpp genutzt. Aber dort ist immer nur die erste #if Bedingung 
aktiv. Ich habe schon in die main.ii und die OneWire.ii geschaut. In der 
main.ii funktioniert die Umschaltung problemlos nur in der OneWire.ii 
sind immer nur die ersten Konstanten aktiv zumal dort auch nicht das 
Schlüsselwort #define OVERRIDE auftaucht.

Wenn ich allerdings im Microchip Studio unter Toolchain -> C++ Compiler 
-> Symbols das Schlüsselwort OVERRIDE eintrage funktioniert es und auch 
in beiden *.ii Dateien ist das Schlüsselwort OVERRIDE vorhanden.

Ist es überhaupt möglich per #define und #if Anweisungen über mehrere 
Dateien zu arbeiten?

C/C++ ist manchmal echt eine verwirrende Sprache aber ich sage mir halt 
immer -selber essen macht dick- weshalb ich mich mich mal durch ein paar 
kleinen Projekten quäle. :D

von Mario M. (thelonging)


Lesenswert?

Manuel F. schrieb:
> Ist es überhaupt möglich per #define und #if Anweisungen über mehrere
> Dateien zu arbeiten?

Ja.

Manuel F. schrieb:
> Wenn ich allerdings im Microchip Studio unter Toolchain -> C++ Compiler
> -> Symbols das Schlüsselwort OVERRIDE eintrage funktioniert es

von Klaus W. (mfgkw)


Lesenswert?

So wie Mario vorschlägt, oder: du schreibst ein #define... in eine 
eigene Header-Datei und #includest die in deinen bisherigen 
Header-Dateien vor der Verwendung dort.

Abgesehen davon, wenn du C++ machen willst (löblicherweise): die meisten 
#define gehören durch const... ersetzt. Man ist das nicht mehr in den 
Siebzigern.

von Manuel F. (dobby)


Lesenswert?

Klaus W. schrieb:
> Abgesehen davon, wenn du C++ machen willst (löblicherweise): die meisten
> #define gehören durch const... ersetzt. Man ist das nicht mehr in den
> Siebzigern.

Das ist ein gutes Stichwort. Ich habe schon überlegt es über die const 
Deklaration zu machen. Dabei könnte ich es sogar in eine normale "If 
Else" oder "Switch" Auswahl schreiben und so die Werte zur Laufzeit 
umschalten.
Jetzt werden aber die Konstanten in mehreren Klassen bzw. Funktionen von 
Klassen verwenden. Sollte man sie jetzt einfach global deklarieren? Was 
ich bis jetzt so gelesen habe, soll man ja nach Möglichkeit globale 
Variablen vermeiden. Da wäre es bestimmt am sinnvollsten eine Funktion 
in der Vaterklasse zu definieren welche die Umschaltung vornimmt und die 
konstanten als Public zu deklarieren?

von Klaus W. (mfgkw)


Lesenswert?

Einfach als const definieren und fertig.

Man soll nicht ohne guten globale VARIABLEN verwenden.
Es geht hier aber um Konstanten.

von Manuel F. (dobby)


Lesenswert?

Okay danke so werde ich es machen.

von DJ P. (djpx)


Lesenswert?

Ich hatte tatsächlich ein Ähnliches Problem mit dem #define.

Manuel F. schrieb:
> Wenn ich allerdings im Microchip Studio unter Toolchain -> C++ Compiler
> -> Symbols das Schlüsselwort OVERRIDE eintrage funktioniert es und auch
> in beiden *.ii Dateien ist das Schlüsselwort OVERRIDE vorhanden.

Defines sind nur für die Datei gültig in welcher sie definiert worden 
sind, außer man schreibt es für den Compiler so, dass er diese defines 
vorher lesen kann rein. (Das ist genau das warum es funktioniert, wenn 
du es so machst) 
https://stackoverflow.com/questions/10916280/how-to-use-define-from-another-file

Du könntest auch so etwas verwenden:
[code]
class Override
{
public:
  static float H = 480, I = 70, G = 0;
  static void setOverride(bool override)
  {
    this.override = override if (override)
    {
      H = 70;
      I = 8.5;
      G = 2.5;
    }
    else
    {
      H = 480;
      I = 70;
      G = 0;
    }
  }
  static bool isOverride(){return override};

private:
  override = false;
};
[code]
Zugriff wäre dann über Override::H zum Beispiel

Und umschalten wäre mit Override::setOverride(true); möglich

Das wäre ein anderer Ansatz aber vielleicht ist dieser ja auch Hilfreich 
für dich. (Code wurde freihand geschrieben und nicht getestet. Ambesten 
würde man noch so Sachen wie getter für die Variablen machen und diese 
Private oder Protectet deklarieren)

Defines verwende ich eigentlich nur wenn ich Platform spezifischen Code 
zum Beispiel für Linux oder Windows schreibe.
Oder zwischen Debug und "Fertigen" Code umschalte.

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.