int a[variable]; ???!



  • hallo leute

    ich hab mich heute mit einem freund aus meinem parallelen informatikkurs utnerhalten. die hören zur zeit ein referat über c++ (also eigendlich ein tutorial) und da ich c++ ganz gut beherrsche hab ich natürlich mal was nachgefragt

    so ists nun der fall dass die referierenden denen folgendes beibringen:

    int main()
    {
        int x;
        cin >> x;
        int array[x];
        // statt   int * array = new int[x];
    
        // DO STH
    }
    

    soweit ich weiss benutzen die ein linux system mit Codebloxx und nem gnu compiler (kA obs genau so stimmt und version weiss ich auch nicht)

    ich habs immer gelernt dass es halt das mit dem pointer ist
    was sagt da der standard zu oder ist das einfahc nur falsch?

    mfg mosho



  • Das geht nicht in C++. Das gibt es aber in C (seit C99) und wird dort VLAs genannt. Aus gutem Grund wird es das aber nicht in C++ geben. Kann aber sein, dass der GCC das als Extension für C++ hat.



  • Skym0sh0 schrieb:

    was sagt da der standard zu oder ist das einfahc nur falsch?

    Das, was du da geschrieben hast, ist kein gültiges C++, denn im aktuellen Standard muss die Größe eines Arrays auf dem Stack ein konstanter Ausdruck sein.



  • ja der meinung bin ich auch
    aber ich wollte halt mal nachfragen

    ich kenne mich nciht so auf den standard komitee seiten aus, wo man was fidnet und so



  • rüdiger schrieb:

    Aus gutem Grund wird es das aber nicht in C++ geben.

    Aus welchem Grund? Ich finde so ein Feature nicht schlecht. Das wäre wie ein new ohne delete[].



  • Z schrieb:

    rüdiger schrieb:

    Aus gutem Grund wird es das aber nicht in C++ geben.

    Aus welchem Grund? Ich finde so ein Feature nicht schlecht. Das wäre wie ein new ohne delete[].

    Ja, und das autet in C++

    std::vector<int> array(x)
    

    Lars



  • Vielleicht, weil's dann an zu vielen Stellen stehen könnte, wo's nicht hingehört.
    z.B. im globalen Bereich, mit extern in Headern, in Klassen/Struct-Deklarationen usw. Eigentlich sieht's ja hübsch aus und würde vermutlich viele Fehler wegen fehlendem delete[] oder nur der Klammern am delete verhindern. Antwort interessiert mich auch.



  • Z schrieb:

    rüdiger schrieb:

    Aus gutem Grund wird es das aber nicht in C++ geben.

    Aus welchem Grund? Ich finde so ein Feature nicht schlecht. Das wäre wie ein new ohne delete[].

    Das Feature ist schlecht, weil es keinen Weg gibt zu überprüfen ob überhaupt noch genug Speicher auf dem Stack vorhanden ist und es gibt keinen Weg den Fehlerfall zu behandeln.

    Ich muss zugeben, dass es auf den ersten Blick gut wirkt. Aber es ist im Endeffekt doch ziemlich böse und alles andere als trivial.



  • Es ist eine potentielle Sicherheitsluecke.



  • Es wäre ein nettes Feature. Nix Sicherheitslücke. Nix Speichermangel. Es wäre SCHNELL.



  • knivil schrieb:

    Es ist eine potentielle Sicherheitsluecke.

    Nur wenn der Compiler nicht überprüft ob genug Speicher auf dem Stack vorhanden ist. (Was der GCC afaik leider nicht tut :()

    volkard schrieb:

    Es wäre ein nettes Feature. Nix Sicherheitslücke. Nix Speichermangel. Es wäre SCHNELL.

    In C++ könnte man mit einer Exception hier vielleicht sogar etwas machen. Wobei etwas ala new(std::onstack) Foo (im Sinne von man: alloca) vielleicht sogar praktischer wäre, weil man dann endlich mal Allocatoren sinnvoll einsetzen könnte und mit einem Schlag die ganzen Container auf den Stack packen kann :).

    Man müsste halt in den Standard schreiben, dass ein Compiler hier überprüfen muss, ob genug Speicher vorhanden ist. Weil leider implementiert der GCC zB alloca ohne Überprüfung 😞



  • rüdiger schrieb:

    knivil schrieb:

    Es ist eine potentielle Sicherheitsluecke.

    Nur wenn der Compiler nicht überprüft ob genug Speicher auf dem Stack vorhanden ist. (Was der GCC afaik leider nicht tut :()

    Mmh? Wie soll er das denn machen?
    Die Grösse ist doch erst zur Laufzeit bekannt!



  • Der Code den er dafür generiert, sollte das zur Laufzeit überprüfen.



  • rüdiger schrieb:

    Der Code den er dafür generiert, sollte das zur Laufzeit überprüfen.

    Das halte ich für irrelevant. Natürlich knallt man noch nicht megabytegroße Sachen auf den Stack. Stacküberlauf macht eben Programmabsturz. Damit hatte ich noch nie Probleme. Ich kann mir nicht vorstellen, daß jemand damit Probleme hat.



  • rüdiger schrieb:

    Wobei etwas ala new(std::onstack) Foo (im Sinne von man: alloca) vielleicht sogar praktischer wäre, weil man dann endlich mal Allocatoren sinnvoll einsetzen könnte und mit einem Schlag die ganzen Container auf den Stack packen kann :).

    Es ist leider nicht möglich, daß der Konstruktor (eine normal aufgerufene Funktion) mit alloca lokalen Stackspeicher holt und an die aufrufende zurückgibt.

    Foo* a=new(std::onstack) Foo;
    

    würde gehen, aber ist ja nicht besser als

    Foo a;
    

    .

    FooVec f(100);//besorgt 100 Plätze auf dem Stack
    

    klappt irgendwie nicht. Vielleicht nett wäre wohl

    FooVec<100> f;
    

    und manche Template-Parameter als Variable erlauben.



  • rüdiger schrieb:

    Z schrieb:

    rüdiger schrieb:

    Aus gutem Grund wird es das aber nicht in C++ geben.

    Aus welchem Grund? Ich finde so ein Feature nicht schlecht. Das wäre wie ein new ohne delete[].

    Das Feature ist schlecht, weil es keinen Weg gibt zu überprüfen ob überhaupt noch genug Speicher auf dem Stack vorhanden ist und es gibt keinen Weg den Fehlerfall zu behandeln.
    Ich muss zugeben, dass es auf den ersten Blick gut wirkt. Aber es ist im Endeffekt doch ziemlich böse und alles andere als trivial.

    Jedes Feature kann man falsch verwenden. Ich stehe mehr auf dem Standpunkt, ein Arsenal von Features zu haben, aus denen man sich für den jeweiligen Fall die Mischung zusammenstellen kann. Sonst können wir gleich nur noch in Java oder C# programmieren. 😉



  • Bjarne's C++0x FAQ:

    C99 features:
    ...
    - Not VLAs (Variable Length Arrays; thank heaven for small mercies).

    klingt so, als wäre er froh, dass VLAs nicht dabei sind. Richtig überzeugende Gründe fallen mir aber für keine Position ein. Es ist ja immer eine Kosten/Nutzen-Rechnung. VLAs müssen sich durch Sonderregeln, Komplexität, Inkonsistenzen erkauft werden. Lohnt sich das?
    - sizeof würde kein reiner Compile-Zeit-Mechanismus mehr bleiben
    - Was ist der Typ eines VLAs? Ist er unvollständig?
    - Wie ist das Zusammenspiel mit Templates? (zB bzgl argument deduction, ...)



  • volkard schrieb:

    rüdiger schrieb:

    Der Code den er dafür generiert, sollte das zur Laufzeit überprüfen.

    Das halte ich für irrelevant. Natürlich knallt man noch nicht megabytegroße Sachen auf den Stack. Stacküberlauf macht eben Programmabsturz. Damit hatte ich noch nie Probleme. Ich kann mir nicht vorstellen, daß jemand damit Probleme hat.

    Jemand hat spätestens Probleme damit, wenn der Stack manchmal überläuft und manchmal nicht, je nach Benutzereingabe (und das am besten schon beim Kunden 😉 ).



  • Z schrieb:

    Jedes Feature kann man falsch verwenden. Ich stehe mehr auf dem Standpunkt, ein Arsenal von Features zu haben, aus denen man sich für den jeweiligen Fall die Mischung zusammenstellen kann. Sonst können wir gleich nur noch in Java oder C# programmieren. 😉

    Klar kann man jedes Feature falsch verwenden. Es gibt aber auch Features die man bestenfalls nur sehr schwer richtig verwenden kann, und dazu gehören die gesamten dynamisch veränderlichen und nicht überprüfbaren Giftmüllexporte aus C-Beständen, wie z.B. die Funktionen der printf-Familie, die keinen Längencheck eingebaut haben, VLAs, variable Argumentlisten, diverse void-Pointer-Frickeleien usw.
    Mehr Features sind durchaus nicht schlecht, wenn sie einen erkennbaren VOrteil bringen. Mehr Features sind aber dann schlecht, wenn sie nur einen kleinen Vorteil bringen und auf Kosten des wichtigsten Features überhaupt gehen: Der Sicherheit.



  • _matze schrieb:

    volkard schrieb:

    rüdiger schrieb:

    Der Code den er dafür generiert, sollte das zur Laufzeit überprüfen.

    Das halte ich für irrelevant. Natürlich knallt man noch nicht megabytegroße Sachen auf den Stack. Stacküberlauf macht eben Programmabsturz. Damit hatte ich noch nie Probleme. Ich kann mir nicht vorstellen, daß jemand damit Probleme hat.

    Jemand hat spätestens Probleme damit, wenn der Stack manchmal überläuft und manchmal nicht, je nach Benutzereingabe (und das am besten schon beim Kunden 😉 ).

    Dann ist er dumm und hat es verdient.
    Mit solchen Argumenten kannst Du auch Zeiger abschaffen und alles über Referenzen machen wollen. Oder delete abschaffen und einen garbage collector einführen.
    Außerdem lege ich jetzt aus Trotz immer 10000-große Arrays auf den Stack und bekomme endlich auch mal einen Ausstieg, wenn der Stack alle ist, und zusätzlich einen, wenn mehr als 10000 Elemente gebraucht werden.

    Stellt euch mal vor, ich hätte eine Template-Klasse, die automatisch die Arrays, die mehr als 1000 Bytes belegen, im Freispeicher anlegt. Muß man da jetzt noch Angst haben? Klar, bei 900 rekursiven Aufrufen wirds langsam eng; aber das zusammen tut echt keiner.


Log in to reply