Compilerfehler künstlich erzeugen
-
uzuzuzuzuz schrieb:
Registrierter Troll schrieb:
Such mal nach
static_assert.Ist das Teil des Standards?
Noch nicht. Ist aber für C++0x vorgeschlagen und wird von vielen Compilern schon heute verstanden.
-
uzuzuzuzuz schrieb:
Registrierter Troll schrieb:
Such mal nach
static_assert.Ist das Teil des Standards?
Das weiß ich auch nicht, aber der S_StaticAssert für boolsche Bedingungen ist schnell geschrieben
template <bool condition> struct S_StaticAssert {}; template<> struct S_StaticAssert<true> { static void check(){;} };S_StaticAssert<(1 < 2)>::check(); //kompiliert; S_StaticAssert<(1 > 2)>::check(); //kompiliert nicht;Greets
Tobi _logoff
-
Sowohl die Loki-Bibliothek als auch Boost haben ein static_assert bzw. ein BOOST_STATIC_ASSERT - und beide sind standardkonform.
-
Zuerst vielen Dank

Mmmh,
was genau ist nach derzeitigem Standard nun erlaubt? Bei
#include <boost/static_assert.hpp>findet der die Datei nicht.
Bzw. der neue Standard brauch doch noch ein 3/4 Jahr, oder? Bei heise.de hab ich so etwas gelesen.
Viele Grüße
MM
-
MrMilk schrieb:
Zuerst vielen Dank

Mmmh,
was genau ist nach derzeitigem Standard nun erlaubt? Bei
#include <boost/static_assert.hpp>findet der die Datei nicht.
Bzw. der neue Standard brauch doch noch ein 3/4 Jahr, oder? Bei heise.de hab ich so etwas gelesen.
Viele Grüße
MMDas Schlüsselwort "static_assert" kommt erst mit dem neuen Standard. Boost ist eine externe Bibliothek, die auf sehr vielen Systemen verfügbar ist und ein äquivalentes Konstrukt bietet. Dieses Konstrukt ist aber mit Mitteln aus dem (jetzigen) C++ Standard aufgebaut - es dürfte sich um das von Tobi_logoff gezeigte oder etwas Ähnliches handeln.
Du kannst also entweder
1.) gucken, ob dein Compiler schon static_assert kennt
2.) die Boost Bibliothek installieren und benutzen
3.) den entsprechenden Teil aus boost abgucken
4.) Tobi_logoffs Code benutzen
-
Benutz lieber den Code von hier. Boost willst du dir nicht antun und der neue Standard braucht eh noch Jahre.
-
randnotiz schrieb:
Benutz lieber den Code von hier. Boost willst du dir nicht antun und der neue Standard braucht eh noch Jahre.
"Boost willst du dir nicht antun" ist ungefähr so sinnvoll wie "das funktioniert nicht" als Fehlermeldung. Warum sollte er es sich nciht antun wollen? Boost ist in 5-10 Minuten instaliert und einsatzbereit, und man muss ja nicht gleich alle Bibliotheken daraus benutzen. Fürs static_assert würde ich zwar auch eher die Loki-Version benutzen, allerdings wenn man boost bereits installiert hat ist das auch durchaus benutzbar. Die oben gepostete Version würde ich vermutlich nicht nutzen, da sie nicht so besonders ausgereift ist.
Hier die Loki-Version:namespace Loki { template<int> struct CompileTimeError; template<> struct CompileTimeError<true> {}; } //////////////////////////////////////////////////////////////////////////////// // macro STATIC_CHECK // Invocation: STATIC_CHECK(expr, id) // where: // expr is a compile-time integral or pointer expression // id is a C++ identifier that does not need to be defined // If expr is zero, id will appear in a compile-time error message. //////////////////////////////////////////////////////////////////////////////// #define LOKI_STATIC_CHECK(expr, msg) \ { Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }
-
pumuckl schrieb:
...
da sie nicht so besonders ausgereift ist.
...Könntest du mir das erklären? Ich seh zur Loki version nur den Unterschied bool und int, in der eigentlichen Metafunktion.

-
Tobi_logoff schrieb:
Könntest du mir das erklären? Ich seh zur Loki version nur den Unterschied bool und int, in der eigentlichen Metafunktion.

Zum einen muss man in deinem Fall den Ausdruck zwischen dem struct-Namen und dem ::check() vergraben, da hätte zumindest noch ein Makro geholfen.
Zum zweiten hat das Loki-Beispiel den Vorteil, dass man eine Aussagekräftige Fehlermeldung dazupacken kann:int main() { S_StaticAssert<(1 < 2)>::check(); //kompiliert; S_StaticAssert<(1 > 2)>::check(); //kompiliert nicht; //line 30 LOKI_STATIC_CHECK(1 < 2, argument_must_be_less_than_2); LOKI_STATIC_CHECK(1 > 2, argument_must_be_greater_than_2); }In function 'int main()': Line 30: error: 'check' is not a member of 'S_StaticAssert<false>' In function 'int main()': Line 33: error: aggregate 'Loki::CompileTimeError<0> [b]ERROR_argument_must_be_greater_than_2[/b]' has incomplete type and cannot be definedIch sag ja nicht dass es völliger Blödsinn ist, der Ansatz ist der richtige. Es fehlen bloß ein paar Kleinigkeiten, und da es die schon fertig zu holen gibt, braucht man das Rad nicht neu erfinden.
-
Boost ist eklig fett.
-
Vielen Dank. Ich habe mich für die Lösung von pumuckl entschieden (es gab viele Google treffer
). Insgesamt ist mein Problem, dass ich nur nach std Programmieren darf und alles was dort nicht enthalten ist, bringt mir ärger.Leider ist mir noch einzweiter Fall eingefallen, den ich gerne mit Comilerfehlern abdecken möchte. Aber hier habe ich die Vermutung, dass man es nicht lösen kann:
template <int Groesse> class Parkhaus { public: Parkplatz() { } protected: Parkplatz<Groesse> Parkeinheiten; } void main (int, char*)[] { Parkhaus<30> p1; Parkhaus<34> p2; //Geld wird investiert, Parkhäuser werden zusammen geführt p1 = p1 + p2; }An dieser Stelle sehe ich noch ein gewaltiges Problem. Und zwar hat p1 nach der Vereinigung der Parkhäuser nun die Kapazität von 64 Parkplätzen. Die Addition der beiden Parkhäuser ist kein Problem. Mit Macros kann ich das Maximum auswerten und ein neues Objekt zurück geben. Aber kann ich dieses Objekt überhaupt zuweisen? Die Typen stimmen ja nicht mehr überein.
Oder liege ich komplett neben der Spur? Wie immer bin ich über jeden Tipp dankbar.
Viele Grüße
MMViele Grüße
MM
-
Seltsames Beispiel. Und ein noch seltsameres main()

Spricht irgendwas dagegen, die Anzahl der Parkeinheiten einfach als Parameter an den Ctor von Parkhaus zu übergeben?
Stefan.
-
Ich denke mal, dass in diesem Fall die einfache Addition der Größen das Problem ist. So einfach liegt der Fall nämlich nicht. Effektiv entstehen ja nicht mehr Parkplätze. Also müßte im gleichen Zug Parkhaus 2 seine Parkplätze einbüßen - worauf es dann zur Bauruine wird, oder was auch immer. Es könnte sich sogar selbst abreißen - besser wäre es jedoch, dies von Parkhaus 1 aus zu machen.
-
MrMilk schrieb:
Leider ist mir noch einzweiter Fall eingefallen, den ich gerne mit Comilerfehlern abdecken möchte.
Dieser Code ist ein einziger Compilerfehler. Mission accomplished.
-
pumuckl schrieb:
Tobi_logoff schrieb:
Könntest du mir das erklären? Ich seh zur Loki version nur den Unterschied bool und int, in der eigentlichen Metafunktion.

Zum einen muss man in deinem Fall den Ausdruck zwischen dem struct-Namen und dem ::check() vergraben, da hätte zumindest noch ein Makro geholfen.
Zum zweiten hat das Loki-Beispiel den Vorteil, dass man eine Aussagekräftige Fehlermeldung dazupacken kann:int main() { S_StaticAssert<(1 < 2)>::check(); //kompiliert; S_StaticAssert<(1 > 2)>::check(); //kompiliert nicht; //line 30 LOKI_STATIC_CHECK(1 < 2, argument_must_be_less_than_2); LOKI_STATIC_CHECK(1 > 2, argument_must_be_greater_than_2); }In function 'int main()': Line 30: error: 'check' is not a member of 'S_StaticAssert<false>' In function 'int main()': Line 33: error: aggregate 'Loki::CompileTimeError<0> [b]ERROR_argument_must_be_greater_than_2[/b]' has incomplete type and cannot be definedIch sag ja nicht dass es völliger Blödsinn ist, der Ansatz ist der richtige. Es fehlen bloß ein paar Kleinigkeiten, und da es die schon fertig zu holen gibt, braucht man das Rad nicht neu erfinden.
Danke...

hätte schon gedacht ich sitze einem Fehler auf, den ich noch nicht gesehen habe.
-
DStefan schrieb:
Seltsames Beispiel. Und ein noch seltsameres main()

Uhh ja, da hast du recht.
Mir geht es nur darum, was passiert, wenn man etwas zuweisen möchte und der Templateparamter (heißt es so, bin mir da nicht sicher?) nicht der gleiche ist.
Ist dieses grundsätzlich nicht möglich oder muss man dann etwas bestimmtes machen...
Viele Grüße
MM
-
ady schrieb:
Boost ist eklig fett.
Wo ist Boost bitteschön "fett"? Die Boost-Bibliotheken sind eine Sammlung von vielen einzelnen Bibliotheken, häufig verwendet man aber in einem Projekt davon nur eine Handvoll.
-
Dann will er wohl einen speziellen + Operator
-
MrMilk schrieb:
Mir geht es nur darum, was passiert, wenn man etwas zuweisen möchte und der Templateparamter (heißt es so, bin mir da nicht sicher?) nicht der gleiche ist.
Das hängt davon ab worum es geht. Wenn es sich z.B. um Vektoren (im Mathematischen Sinn) handelt und der Templateparameter die Zahl der Dimensionen angibt, dann kann man sie einfach nicht addieren. Wenns sich um etwas handelt, wo das Ergebnis einen neuen Templateparameter hat, muss man den entsprechend berechnen, bei deinen Parkhäusern würde ich (wenn auch unter Zahnschmerzen, weil das Beispiel haarsträubend ist) in etwa folgendes machen:
template <int n1, int n2> parkhaus<n1+n2> operator+ (parkhaus<n1> const& lhs, parkhaus<n2> const& rhs) { parkhaus<n1+n2> presult; presult.setAdresse( funnyAdressMix(lhs.getAdresse(), rhs.getAdresse() ); presult.setParkPreis( (n1*lhs.getParkPreis() + n2*rhs.getParkPreis())/(n1+n2) ); //und was auch immer die Semantik so einer sinnfreien Addition sein könnte ;) };Ich hab noch nie gesehen wie jemand Bauwerke addiert. Du?
-
Hallo Pumuckl,
na klar ist die Semantik nicht besonders gut gewählt. Eventuell wäre das Mischen von Flüssigkeiten besser gewesen
Ist mit leider erst jetzt eingefallen.Aber was du da programmierst hast, hatte ich auch vor. Für mich ist nun interessant, was passiert bei einer Zuweisung?
Muss ich dann immer ein neues Objekt deklarieren. Im Allgemeinen ist n1 + n2 ungleich n1.
Dann sofort ein Objekt Parkhaus<n1 + n2> neuespkh deklarieren? Das ganze nach p1 zuweisen sollte ja nicht klappen.Viele Grüße
MM