Hallo,
ich habe eine h Datei mit einem Compilerswitch.
Diese h Datei inkludiere ich in Cpp files.
In einem Cpp file (a.cpp) setze ich den Compilerswitch.
Darin ist nach meinem Verständnis dann die variable var definiert.
In einem anderen Cpp file (b.cpp) inkludiere ich auch diese h Datei
allerdings ohne setzen des Compilerswitches.
var ist ja bereits definiert und ich möchte sie woanders lesen.
Aus der h Datei
:
#if defined(switchA)
int var = 9;
#else
extern int var;
#endif
:
Im jeweiligen cpp file kann ich lesend auf var zugreifen. Ihr Wert ist
in beiden Fällen 9.
Setze ich nun const ein, bekomme ich folgende Fehlermeldung:
"undefinde reference to var."
Zum einen verstehe ich nicht warum ich die Fehlermeldung bekomme
und was müsste ich tun, damit
Aus der h Datei
:
#if defined(switchA)
const int var = 9;
#else
extern const int var;
#endif
:
Sven schrieb:> Aus der h Datei> :> #if defined(switchA)> int var = 9;> #else> extern int var;> #endif> :
Warum machst du sowas? Die Definition der Variablen hat im Header nichts
zu suchen.
> Setze ich nun const ein, bekomme ich folgende Fehlermeldung:>> "undefinde reference to var."
In C++ haben Konstanten "internal linkage". Man kann also nicht per
extern darauf zugreifen.
Rolf M. schrieb:> In C++ haben Konstanten "internal linkage". Man kann also nicht per> extern darauf zugreifen.
Eine Frage, die mir durch den Kopf geht: Hat der "const int" in allen
Sources, die den Header einbinden, die selbe Addresse? "internal
linkage" klingt erst einmal nicht so.
Danke und sorry, hat mir alles leider irgendwie nicht weitergeholfen.
Erster Code snippet funktioniert.
Hier kann ich schreibend und lesend auf var in den cpp Dateien
zugreifen.
Zweiter Code snippet funktioniert nicht.
Hier will ich nur lesend zugreifen mit const zulassen.
Ja, ich weiß, die var Definition kann ich auch in eine cpp Datei packen.
Ich frage aber nach der Möglichkeit dies in einer h Datei zu machen.
Rolf M. schrieb:> In C++ haben Konstanten "internal linkage". Man kann also nicht per> extern darauf zugreifen.
Bedeutet es gibt in dem Header Ansatz keine Möglichkeit.
extern und const geht nicht.
Warum da schreiben und lesen geht aber nur lesen nicht, ist zumindest
für den nicht Vollprofi schwer zu verstehen.
Die Variablen Definition gehört in eine cpp Datei.
test.h
1
#pragma once
2
externconstintvar;
test.cpp
1
#include test.h
2
constintvar=6;
Rolf M. schrieb:> In C++ haben Konstanten "internal linkage". Man kann also nicht per> extern darauf zugreifen.
Gut das mein Compiler das nicht weiß!
Denn der tut das
avr-gcc-11.1.0-x64-windows -std=gnu++17
Vincent H. schrieb:> Besser:inline constexpr int var = 9;
Warum nicht sofort static inline constexpr int var {9};
Ob static oder/und inline, oder keins von beiden, bleibt sich gleich
EAF schrieb:> Gut das mein Compiler das nicht weiß!> Denn der tut das
Der weiß das, und tut das genauso wenig wie beim TO. Du hast das Problem
nicht ganz verstanden.
Oliver
EAF schrieb:> Ob static oder/und inline, oder keins von beiden, bleibt sich gleich
Nein, ohne inline steht es dem Compiler frei für jede Source Datei eine
Kopie von var anzulegen. Das mag bei einem int noch egal sein, aber wenn
es sich um zig-kB große Arrays handeln würde wär das für Mikrocontroller
wohl nicht so wünschensweert.
EAF schrieb:> Dann sage mir doch bitte wo mein Denkfehler ist.
Du brauchst nur den Ausgangsbeitrag richtig zu lesen. Hinweis: Zähl mal,
um wieviele Dateien es da geht (und warum es die defines überhaupt
brauchen könnte).
Oliver
Vincent H. schrieb:> Nein, ohne inline steht es dem Compiler frei für jede Source Datei eine> Kopie von var anzulegen. Das mag bei einem int noch egal sein, aber wenn> es sich um zig-kB große Arrays handeln würde wär das für Mikrocontroller> wohl nicht so wünschensweert.
Allerdings sind die Compiler und Linker ziemlich gut darin,
constexpr-Variable ganz zu eliminieren.
Oliver
EAF schrieb:> Rolf M. schrieb:>> In C++ haben Konstanten "internal linkage". Man kann also nicht per>> extern darauf zugreifen.> Gut das mein Compiler das nicht weiß!> Denn der tut das> avr-gcc-11.1.0-x64-windows -std=gnu++17
Dann ist er wohl irgendwie kaputt. Bei meinem kommt jedenfalls wie zu
erwarten eine "undefined reference to `var'".
Tja,
könnte bitte jemand hier ein code snippet reinkopieren von dem er weiß,
das es funktionieren tut? Definition in einer h Datei mit
Compilerswitch.
Die Variante mit Aufteilung in cpp und hpp bekomme ich hin.
Es wurde ja viel geschrieben aber pragmatisch geholfen leider noch
nicht.
Google habe ich auch schon bemüht.
Ich kann nur sagen, das funktioniert bei mir nicht
1
:
2
#if defined(switchA)
3
constintvar=9;
4
#else
5
externconstintvar;
6
#endif
7
:
und alle Abwandlungen mit extern, constexpr, inline und Kombinationen
funktionieren auch nicht.
Das funktioniert:
Sven schrieb:> Tja,> könnte bitte jemand hier ein code snippet reinkopieren von dem er weiß,> das es funktionieren tut? Definition in einer h Datei mit> Compilerswitch.Oliver S. schrieb:>
1
>#ifdefined(switchA)
2
>externconstintvar=9;
3
>#else
4
>externconstintvar;
5
>#endif
6
>
>> Wie aber schon geschrieben wurde, mach das nicht (für POD-Datentypen).> Dafür gibt es constexpr.
Oliver
Hallo Oliver,
Das funktioniert!
Ich hatte obiges extern übersehen. Frage mich auch ein wenig, wieso das
da sein muss. Das untere extern wäre mir klar.
1
:
2
#if defined(switchA)
3
externconstintvar=9;
4
#else
5
externconstintvar;
6
#endif
7
:
Was auch funktioniert:
Soweit ich nachgelesen habe sagt constexpr aus das es sich hier um eine
Variable handelt, die explizit zur Compilezeit bekannt ist.
Sie muss da wohl auch initialisiert sein sonst zeigt das der Compiler
an.
Der zweite Teil mit
1
externconstintvar;
Wird somit wohl nur so funktionieren und
kann nicht mit constexpr funktionieren? Oder?
Sven schrieb:> Wird somit wohl nur so funktionieren und> kann nicht mit constexpr funktionieren? Oder?
Mit constexpr brauchst du kein extern. Du schreibst in deinen Header
einfach:
1
constexprintvar=9;
und sonst nichts. Kein Compiler-Switch, kein extern.
im Header ist sichergestellt, dass diese Variable nur einmal angelegt
wird?
Sie soll nur einmal angelegt werden und nicht in jeder cpp
Übersetzungseinheit.
Im www habe es nun so verstanden das
in C++17 diese
1
inlineconstexprintvar=9;
Definition in einem Header sein kann
und dieser Header kann in x beliebigen cpp Dateien inkludiert sein.
Es wird nur einmal angelegt.
Ob da nun inline davor muss oder der Compiler da was macht weiss ich
net.
So wie oben wäre es aber wohl nicht verkehrt.
Sven schrieb:> Es wird nur einmal angelegt.
Es wird maximal einmal angelegt. Wie schon mehrfach angedeutet wurde,
wird (bei eingeschalteter Optimierung) der Compiler die letztendlich gar
nicht anlegen, sondern überall direkt den Wert einsetzen.
Oliver