Array mit externer Konstante ???



  • itman schrieb:

    Das arbeitet nitch mit Visual C, und auch mit keinem standarten C++ Compiler weil Compiler bei der Compile-Zeit Array-Groesse wissen muss!

    Weiß er doch. Bist Du übrigens sicher dass das nicht legal ist? Comeau schluckt das auch ohne zu meckern...

    1. new
    2. vector, links (STL)
    3. alloca funktion (das Vorteil ist dass es Speicher im Stack allockiert und du es nicht freine soll)

    Die diversen Standardcontainer sind natürlich eine feine Sache, aber von der Verwendung von alloca würde ich in C++ absehen - ist außerdem doch nicht standardisiert, oder?



  • nman schrieb:

    itman schrieb:

    Das arbeitet nitch mit Visual C, und auch mit keinem standarten C++ Compiler weil Compiler bei der Compile-Zeit Array-Groesse wissen muss!

    Weiß er doch. Bist Du übrigens sicher dass das nicht legal ist? Comeau schluckt das auch ohne zu meckern...

    1. new
    2. vector, links (STL)
    3. alloca funktion (das Vorteil ist dass es Speicher im Stack allockiert und du es nicht freine soll)

    Die diversen Standardcontainer sind natürlich eine feine Sache, aber von der Verwendung von alloca würde ich in C++ absehen - ist außerdem doch nicht standardisiert, oder?

    Uuups, jetz bin ich nicht sicher. Standard vordert die Array-Groesse constant-expression zu sein, aber denn sa ich keinen Wiederspruch wenn ein Funktion-parameter als const deklariert ist, z.B:

    void f(const int size) {
     int arr[size];
    }
    

    ... und ueber alloca: na ja das ist gar kein best Variante (und nicht standard-conform dabei)



  • itman schrieb:

    Uuups, jetz bin ich nicht sicher. Standard vordert die Array-Groesse constant-expression zu sein, aber denn sa ich keinen Wiederspruch wenn ein Funktion-parameter als const deklariert ist, z.B:

    void f(const int size) {
     int arr[size];
    }
    

    Der Standard verlangt nicht nur eine constant-expression, sondern eine Compiletime Konstante.

    Achtung Werbung:

    http://tutorial.schornboeck.net/konstanten.htm schrieb:

    Bei Konstanten gibt es 2 wichtige Sachen zu unterscheiden: Runtime-Konstanten und Compiletime-Konstanten. Runtime heißt Laufzeit, also erst während der Ausführung des Programmes. Compiletime-Konstanten stehen allerdings schon fest, wenn das Programm kompiliert wird:

    Der Compiler macht aus int i=5*2; direkt ein int i=10; Denn 5 und 2 sind Compiletime-Konstanten, und mit diesen kann der Compiler zaubern.

    Eine Variable die als const deklariert ist, muss keine Compiletime-Konstante sein:

    #include<iostream>
        using namespace std;
    
        int main()
        {
          int t;
          cin>>t;
          int const Konstante=t;
        }
    

    Es ist offensichtlich, dass Konstante zwar konstant ist, aber trotzdem erst zur Runtime feststehen kann. Bei int const i=5; ist i wiederum eine Compiletime-Konstante.

    int i=5;
        int const c=i;
    

    Ist c eine Compiletime Konstante oder eine Runtime Konstante? Obwohl der Wert von c garantiert 5 beträgt, so ist i eben keine Konstante und kann somit (theoretisch) geändert werden. i muss also nicht zwangsläufig den Wert 5 haben wenn wir c initialisieren. Für uns ist das offensichtlich, aber der Compiler hält sich an eine Regel: eine Konstante ist nur dann eine Compiletime Konstante, wenn der Wert mit dem sie initialisiert wird eine Compiletime Konstante ist. Und i ist definitiv keine Compiletime Konstante.



  • Shade Of Mine schrieb:

    Der Standard verlangt nicht nur eine constant-expression, sondern eine Compiletime Konstante.

    Kannst du den Standard zitieren, Ich habe nur "Draft # ..." und keine vollendete Version. Aber ich konnte es nur ueber constant-expression finden. Und keine Erwaehnung dass diese Konstante ist Compiletime Konstante.



  • OK, der C++ Standard verlangt eine 'constant-expression', aber 5.19 [expr.const] definiert eine 'constant-expression'.

    Und da steht ganz schön:

    An integral constant-expression can involve only [..] const variables or static data members of integral or enumeration types initialized with constat expression [..].



  • a, ok. denn hast du recht.



  • itman schrieb:

    Denn ist in diesem Beispliel size eine constant-expression?

    void f(const inst size)
    {
     int c[size];
    }
    

    nein, wo ist denn der wert von size eine constant expression?
    Man beachte das 'initialized with a constant expression'.

    Wenn du mich jetzt aber fragst wo im standard steht, dass

    void f(int const size)
    {
      int a[size];
    }
    ...
    f(7);
    

    nicht erlaubt ist, muss ich passen. Sogerne durchsuche ich den Standard nicht.

    Aber beachte, dass

    void f(int);
    //und
    void f(int const);
    

    die selbe Funktion deklarieren.

    Der Compiler kann also von der Deklaration nicht darauf schliessen ob der Parameter auch in der Definition const ist... bzw. umgekehrt.

    Wo das jetzt aber im Standard steht -> keine Ahnung



  • ok, ok, du bist einfach so schnell, Ich konnte meine unrichtige Antwort nicht loeschen 🙂 einfach verspaetete mich ein wenig 🙂



  • itman schrieb:

    ok, ok, du bist einfach so schnell

    sorry. hab nicht auf die Uhrzeit gesehen, mein Fehler.



  • Wenn du mich jetzt aber fragst wo im standard steht, dass

    void f(int const size) 
    { 
    int a[size]; 
    } 
    ... 
    f(7);
    

    nicht erlaubt ist, muss ich passen. Sogerne durchsuche ich den Standard nicht.

    Bist du sicher, dass es nicht standard konform ist? Ich habe zwar keine Kopie des Standards aber in einem Buch (glaub es war Thinking in C++) wurde folgender Code verwendet:

    int a(){return 4;}
    ...
    char b[a()];
    

    Da das return von a at compile time bekannt ist. Also wäre das oben eigentlih nur logisch.

    Allerdings kämme es von der Implementirung her einem Template gleich.

    Allerdings ist es auch möglich, dass ich Quatsch geredet habe (lasse mich gern korrigiren)



  • *** schrieb:

    Da das return von a at compile time bekannt ist. Also wäre das oben eigentlih nur logisch.

    Allerdings kämme es von der Implementirung her einem Template gleich.

    Allerdings ist es auch möglich, dass ich Quatsch geredet habe (lasse mich gern korrigiren)

    Ich verlass mich jetzt darauf, dass das mit dem return stimmt.
    Ich kann es mir deshalb vorstellen, weil der Compiler weiss, dass a() 4 returned - und das kann unter keinen Umständen anders sein. Sprich er ersetzt a() einfach durch 4.

    Aber wie willst du das bei einem Funktionscall machen?

    Der Compiler kann nicht wissen, dass man f() immer nur mit 7 aufruft. Alleine wen man f() einmal mit 8 aufruft läuft es ja nichtmehr da er dann anderen Code erzeugen müsste.



  • Hier kannst du eine nix vollendete Fassung finden,
    ftp://ftp.research.att.com/dist/c++std/WP/CD2/ .



  • Ich verlass mich jetzt darauf, dass das mit dem return stimmt.
    Ich kann es mir deshalb vorstellen, weil der Compiler weiss, dass a() 4 returned - und das kann unter keinen Umständen anders sein. Sprich er ersetzt a() einfach durch 4.

    Ich weis nicht ob das mit dem return stimmt aber so steht das da drin. Die 4 ist zwar ein template Konstante:

    template<class a,int b>
    int get_array_size(const a[b]){return b;}
    

    Allerdings läuft es auf das gleiche heraus. Mein Kompiler schluckt es allerdings nicht (allerdings wäre das nicht die erste Abweichung vom Standard).

    Aber wie willst du das bei einem Funktionscall machen?

    Wie bereits gesagt von der Implementirung her wäre es mit Templates gleich zu stellen.



  • *** schrieb:

    Wie bereits gesagt von der Implementirung her wäre es mit Templates gleich zu stellen.

    Dann brauchst du auch Templates. Denn Templates ohne template geht nicht.

    Das:

    template<class a,int b>
    int get_array_size(const a[b]){return b;}
    

    ist korrekt, da für jedes Array eine eigene funktion get_array_size() 'angelegt' wird.



  • Shade Of Mine schrieb:

    *** schrieb:

    Wie bereits gesagt von der Implementirung her wäre es mit Templates gleich zu stellen.

    Dann brauchst du auch Templates. Denn Templates ohne template geht nicht.

    Das:

    template<class a,int b>
    int get_array_size(const a[b]){return b;}
    

    ist korrekt, da für jedes Array eine eigene funktion get_array_size() 'angelegt' wird.

    Es ging mir ja nicht um die Funktion selbst sondern die Weise wie man sie benutzen kann (soll können):

    int a[5];
    short b[get_array_size(b)];
    

    Und hier kann gar kein Funktionaufruf statfinden (und wahrscheinlich wird deswegen auch keine Funktion angelegt).


Anmelden zum Antworten