templates und static variables - wieso kompiliert das?

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

templates und static variables - wieso kompiliert das?

Beitrag von kaiserludi »

Folgender Code

Code: Alles auswählen

template<bool isTrue> struct IsTrue;
template<> struct IsTrue<true>
{
};

struct Test
{
	IsTrue<false> failToCompileIfNotTrue;
};
wirft mir wie erwünscht und erwartet einen Kompilierfehler:
'Test::failToCompileIfNotTrue' uses undefined struct 'IsTrue<isTrue>'
1> with
1> [
1> isTrue=false
1> ]
Mache ich die Variable hingegen static

Code: Alles auswählen

template<bool isTrue> struct IsTrue;
template<> struct IsTrue<true>
{
};

struct Test
{
	static IsTrue<false> failToCompileIfNotTrue;
};
so kompiliert der ansonsten unveränderte Code plötzlich seltsamerweise.

Genauso kompiliert das, wenn es in eine lokale Variable in einer Funktion innerhalb von Test ist.

Kann sich das (bzw. mir den Grund) wer erklären?

Die Frage ist eher interessehalber. Habe das eigentlich Problem jetzt anders gelöst (wozu habe ich schließlich COMPILE_TIME_ASSERT_TRUE ...)
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: templates und static variables - wieso kompiliert das?

Beitrag von Krishty »

Das mag kompilieren, wird aber nicht linken. Was du da hinschreibst, ist nämlich bloß eine Deklaration einer externen Variable.

Der Compiler erwartet nun -- wie bei allen externen Variablen -- dass in irgendeinem anderen Modul sowohl IsTrue<false> als auch die Klassenvariable isTrue<false> Test::failsToCompileIfNotTrue definiert sind.

Das geht so mit allen nicht definierten Klassen und statischen nicht-konstanten nicht-integralen Variablen ... weil sie in keiner Instanz der Klasse landen, sondern global einzigartig sind (und von ein paar Compilern auch als globale Variablen behandelt werden), braucht der Compiler sie zum Zeitpunkt der Definition von class Test nicht, um die Auslegung von Instanzen der Klasse zu kennen. Darum kümmert er sich an dieser Stelle auch nicht drum.

Aus demselben Grund musst du Klassenvariablen vom Typ wie z.B. float ja auch einmal in der Klassendefinition deklarieren und in einer anderen Datei definieren. Statische integrale Typen sind die einzige Ausnahme weil C++ scheiße ist bis mein Lieblings-Compiler constexpr kann.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: templates und static variables - wieso kompiliert das?

Beitrag von kaiserludi »

Krishty hat geschrieben:Das mag kompilieren, wird aber nicht linken.
Wenn es denn so wäre, wärs mir recht, aber es linkt auch einwandfrei :(

PS:
*seufz* constexpr könnte ich jetzt auch gerade gut gebrauchen.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: templates und static variables - wieso kompiliert das?

Beitrag von BeRsErKeR »

Wenn du die statische Membervariable nie benutzt gibts keine Probleme beim Linken. Wenn du sie aber nutzt erhälst du bereits einen Fehler beim Compilen. Gleiches gilt auch wenn du sie definierst (was man in der Regel bei statischen Membern tun muss). Krishty hat vollkommen Recht, aber wie gesagt gibts keine Linker-Fehler weil die Membervariable schlicht und ergreifend nie benutzt wird.

Ohne static ist das was anderes, da beim Instanziieren der Test-Klasse die Member-Variable ebenfalls instanziiert wird.

Auch globale Variablen (die prinzipiell fast das gleiche wie statische Membervariablen sind) zeigen das gleiche Verhalten:

Code: Alles auswählen

extern IsTrue<false> failToCompileIfNotTrue;
Geht auch ohne Probleme durch Compiler und Linker. ;)
Ohne Input kein Output.
Antworten