initializer element is not constant



  • Tag zusammen,

    kann mir von euch jemand erklären, warum gcc (und soweit ich das überblicke auch der C-Standard) etwas gegen diesen harmlos aussehenden Code hier hat?

    const int foo = 23;
    int bar = foo;
    

    (foo und bar sollen hierbei beide global sein)

    gcc sagt dazu:

    test.c:2: error: initializer element is not constant

    Wieso bitte ist eine Konstante hier auf einmal nicht konstant?! 😮

    Und gibt es irgendeine Möglichkeit, dieses Problem zu lösen, ohne die Initialisierung von bar in eine Funktion zu verschieben, und ohne aus foo ein #define zu machen?



  • In C zählen 'const int' nicht als konstante Ausdrücke, sondern als lediglich unveränderliche Variablen - und können deshalb auch nicht dort verwendet werden, wo konstante Ausdrücke benötigt werden.

    (C++ ist da flexibler)



  • huch?, das finde ich auch sehr seltsam. ...aber mach doch #define foo 23
    echte konstanten bekommt man sowieso nur mit #define hin.

    CStoll schrieb:

    (C++ ist da flexibler)

    const_cast<x> 😃



  • Apeman schrieb:

    CStoll schrieb:

    (C++ ist da flexibler)

    const_cast<x> 😃

    Nein 😉

    Erstens gilt das "const int foo=23;" in C++ als "echte Konstante" - und zweitens kann man globale Variablen auch mit nicht-konstanten Werten initialisieren (bzw. per Ctor).



  • CStoll schrieb:

    Erstens gilt das "const int foo=23;" in C++ als "echte Konstante"

    na, wenigstens hast du 'echte konstante' in anführungszeichen gesetzt 😉



  • Danke... ich hatte halt irgendwie gehofft, daß es eine einigermaßen schöne Lösung hierfür gibt. Aber gut, dann eben eine häßliche 😉

    Trotzdem kommt es mir so vor, als wenn C einem hier das Leben ohne wirklich guten Grund schwer macht...



  • Apeman schrieb:

    CStoll schrieb:

    Erstens gilt das "const int foo=23;" in C++ als "echte Konstante"

    na, wenigstens hast du 'echte konstante' in anführungszeichen gesetzt 😉

    Was meinst du damit? Das foo ist in C++ konstant genug, um zur Compilezeit bereits verwendet zu werden (auch an Stellen, wo du in C eine #define-Konstante benötigst, wie z.B. zur Angabe einer Arraygröße).

    @domi: Diese Einschränkung hat vermutlich einen Grund, den nur nicht jeder Anwender sofort erkennt 😉



  • CStoll schrieb:

    Was meinst du damit? Das foo ist in C++ konstant genug, um zur Compilezeit bereits verwendet zu werden...

    es gibt kein 'konstant genug' genau so wenig wie 'tot genug' oder 'schwanger genug'. aber lassen wir das, wird zu philosophisch 😉



  • probier mal static const int



  • rüdiger schrieb:

    probier mal static const int

    'static' dürfte bei globalen variablen in dem zusammenhang nicht viel bringen.
    🙂



  • Apeman schrieb:

    es gibt kein 'konstant genug' genau so wenig wie 'tot genug' oder 'schwanger genug'. aber lassen wir das, wird zu philosophisch 😉

    Dann sagt es doch einfach wie es ist: In C++ ist das Ding konstant, in C nicht.



  • LordJaxom schrieb:

    Apeman schrieb:

    es gibt kein 'konstant genug' genau so wenig wie 'tot genug' oder 'schwanger genug'. aber lassen wir das, wird zu philosophisch 😉

    Dann sagt es doch einfach wie es ist: In C++ ist das Ding konstant, in C nicht.

    in beiden nicht.
    --> http://c2.com/cgi/wiki?ConstIsaVirus
    🙂



  • Apeman schrieb:

    in beiden nicht.
    --> http://c2.com/cgi/wiki?ConstIsaVirus
    🙂

    Soll dieser Artikel als Beleg für diese Aussage dienen?



  • LordJaxom schrieb:

    Soll dieser Artikel als Beleg für diese Aussage dienen?

    sorry, das war der falsche. ich meinte den: http://c2.com/cgi/wiki?AvoidConstCompletely
    🙂



  • Apeman schrieb:

    sorry, das war der falsche. ich meinte den: http://c2.com/cgi/wiki?AvoidConstCompletely
    🙂

    Versteh' ich immernoch nicht:

    When we avoid const completely, we never (OK, almost never) use the ConstQualifier in C++ programs as a modifier of a pointer or reference[...]

    Uses of const that act like Java's final keyword--declaring a local variable or class member to be of type "const int", are OK

    Ich finde dort nicht die Aussage, dass eine const Variable auf Namespaceebene nicht konstant ist. Ich finde hier sogar eine explizite Aussage, dass die Benutzung dieser Art von const Ok ist (wobei ich Variablen auf Namespaceebene zu dem zweiten Zitat hinzu-impliziere, da es diese in Java nicht gibt).



  • du hättest etwas weiter lesen sollen:

    const promises very little. Const is not a synonym with "immutable"
    ...
    There can be, of course, non-const pointers to the object which can mutate the object. (And of course, you can always create such a pointer with by CastingAwayConst).
    ...
    The ConstQualifier's main purpose is HelpingTheCompiler; it has almost zero use in describing the user's problem.

    oder anders: const != konstant
    --> http://c2.com/cgi/wiki?PhysicalConst
    🙂



  • Apeman schrieb:

    echte konstanten bekommt man sowieso nur mit #define hin.

    enum { KONSTANTE = 102 };
    


  • cpt. obvious schrieb:

    Apeman schrieb:

    echte konstanten bekommt man sowieso nur mit #define hin.

    enum { KONSTANTE = 102 };
    

    oh, sorry. ich hab' die guten enums vergessen. 😞



  • Apeman schrieb:

    cpt. obvious schrieb:

    Apeman schrieb:

    echte konstanten bekommt man sowieso nur mit #define hin.

    enum { KONSTANTE = 102 };
    

    oh, sorry. ich hab' die guten enums vergessen. 😞

    Ja eben, und ein const int auf Namespace-Ebene ist so konstant wie KONSTANTE. Im Übrigen trifft Dein letztes Zitat auf dieses const IMHO garnicht zu, weshalb der Autor wohl auch die Einschränkung im von mir zitierten Teil gemacht hat 😉



  • LordJaxom schrieb:

    Ja eben, und ein const int auf Namespace-Ebene ist so konstant wie KONSTANTE.

    ne, eben nicht. das hier:

    const int not_const = 123;
    
    int main ()
    {
        *(int*)&not_const = 456; 
    }
    

    sollte in C und C++ compilieren, aber es wird sehr wahrscheinlich crashen (undefiniert). in C++, mit einem const_cast<int> statt (int) versehen, wär' der code womöglich sogar okay .
    dagegen bieten #defines und enums keine möglichkeit für solche faxen. darum sind sie wirklich 'const'
    🙂


Anmelden zum Antworten