Problem bei dateiübergreifender bedingter Komilierung mit #define #ifdef

Hallo,

wollte gerne eine bedingte Kompilierung in einem Modul das zum Projekt gehört durch ein #define im .ino File steuern, aber Dateiübergreifend hats ledier nicht hin. Habe mal ein Beispiel erstellt:

.ino

#define _DO         // Does not influence B.h and B.ccp

#include "B.h"

int A = 2;    // global Var

void setup() {
  Serial.begin(230400);
  Serial.println();
  Serial.println("Starting..");

foo();
}

void loop() {
  // put your main code here, to run repeatedly:
}

Modul B.h:

#ifndef B_H
#define B_H

#include <Arduino.h>     // general Arduino defines

//#define _DO     // if en/disabled here it works

extern int A;     // extern global var (in .ino)

void foo();

#endif

B.cpp:

#include "B.h"

#ifdef _DO

void foo(){
  Serial.print("_DO IS defined, A = ");
  Serial.println(A);
}

#else

void foo(){
  Serial.print("_DO NOT defined, A = ");
  Serial.println(A);
}

#endif

Eigentlich sollte es doch so Funktionieren, denn genau so arbeitet doch die Verhinderung der Mehrfacheinbindung

#ifndef B_H
#define B_H

der .h Datei auch, oder habe ich etwas übersehen?
Vielen Dank!

Sichtbarkeit
Ist das Zauberwort

Deine cpp Datei sieht nur die B.h
Dein #define steht aber in der *.ino

Wenn du _DO auswerten willst, kannst du das in der B.h Datei tun, nicht in der B.cpp

Vielen Dank für den Tip!

Habe mal in die B.h folgendes hinzugefügt:

#ifdef _DO

#define _BO

#endif

und in der B.cpp _DO auf _BO geändert.

Leider geht es so auch nicht :frowning:

Habe gerade das hier gefunden, ...ist scheinbar ein "größeres" Problem??

Serenifly:
Das löst das aber glaube ich auch nicht. Visual Micro macht hier auch nur das was die Arduino IDE macht. Es hilft nur dabei zu sehen was erkannt wird und was nicht.

Es gibt soweit ich weiß mindestens zwei Punkte wo die "Arduino Magie" totalen Murks macht:
1.) bedingte Kompilierung mit #include Direktiven
2.) Funktionsprototypen mit templates und typedefs

Da gibt es auf github zu dem Problem mit den Funktionsprototypen einige Themen
Make sketch preprocessing optional · Issue #2406 · arduino/Arduino · GitHub
In Zukunft kann man das vielleicht mal abschalten:
Preference for toggling preprocessor prototype generation by JeffBobbo · Pull Request #2324 · arduino/Arduino · GitHub

hmm... Aus den links von Serenifly bin ich leider nicht viel schlauer geworden, (liegt aber an mir)
... und wie macht man das nun mit der Arduino IDE? gibt es da ein work-arround - Außer dass halt die #defines in den jeweiligen .h Dateien stehen müssen? :confused:

Hallooo.....

Falscher Dampfer!!
Die Compiler Durchläufe finden getrennt statt!

Erst der Linker baut alles zusammen.

Wenn auch in einem Durchlauf (Kompilation der *.ino) der B.h dein _DO bekannt ist, dann sieht doch die B.h bei der Kompilation von B.cpp kein _DO.
Denn die B.h geht 2 mal durch den Kompiler.

gibt es da ein work-arround

Das was du da im Netz an Problemchen gefunden hast, hat nichts , überhaupt nichts mit deinem Problem zu tun.
Du hast ein Verständnis Problem mit dem was der Kompiler tut.
Was JEDER C/C++ Kompliler genau so tut.
Betrachte es aus dem Kompilerblickwinkel, und projiziere nicht deine Wünsche auf das Kompilerverhalten. Denn der gehorcht nicht deinen Wünschen, sondern er tut das wofür er gemacht wurde.

Alternativ:

Du könntest dir eine Übergeordnete config.h bauen.
Da kommt dann dein #define _DO rein

Dann machst du in jeder (.h,.ino) Datei, welche es braucht ein #include "config.h"

jim_beam:
hmm... Aus den links von Serenifly bin ich leider nicht viel schlauer geworden, (liegt aber an mir)
... und wie macht man das nun mit der Arduino IDE? gibt es da ein work-arround - Außer dass halt die #defines in den jeweiligen .h Dateien stehen müssen? :confused:

Im Anhang eine Zip, welche dir zeigt, wie es gehen kann.

Bei dieser (config.h) Variante ist auch dieser Spruch hinfällig:

Wenn du _DO auswerten willst, kannst du das in der B.h Datei tun, nicht in der B.cpp

error_def.zip (953 Bytes)

jim_beam:
Habe gerade das hier gefunden, ...ist scheinbar ein "größeres" Problem??

Das war was ganz anderes. Da gibt es ein Problem wenn du sowas machst:

#ifdef USE_ALT_SOFT_SERIAL
   #include <AltSoftSerial.h>
   ...
#else
   ...
#endif

Eben ein #include innerhalb eines #ifdef. Das bringt wieder mal den Arduino Präprozessor durcheinander. Was du hast ist wie gesagt ein allgemeines C/C++ Problem

Eben ein #include innerhalb eines #ifdef. Das bringt wieder mal den Arduino Präprozessor durcheinander.

Der Arduino Präprozessor behandelt doch nur *.ino Dateien...
Oder?

Wenn das in *.h oder/und *.cpp Dateien steckt ist damit Ruhe.
(meine Erfahrung)

Klasse, jetzt funktioniert es! Vielen Dank! :wink:

combie:
Der Arduino Präprozessor behandelt doch nur *.ino Dateien...

Ja, denke schon, aber wie gesagt sind das sowieso zwei verschiedene Dinge

jim_beam:
Klasse, jetzt funktioniert es! Vielen Dank! :wink:

Glückwunsch!

Und, wie haste es jetzt gemacht?

Wie von Dir vorgeschlagen...

Die "globalen" Defines in eine eigene config.h und diese über all dort includiert, wo das "globale" Define berücksichtigt werden soll. :slight_smile: