Announcement

Collapse
No announcement yet.

Konstanter Ausdruck zur Arrayinitialisierung

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Konstanter Ausdruck zur Arrayinitialisierung

    Hallo,

    habe jetzt auch mal 'ne Frage:
    Ich möchte unter VS2005 einen Zwischenpuffer für die Funktionen _itoa(), etc. anlegen, in dem der erzeugte String abgelegt wird. Jetzt wollte ich das schön (i. e. Compilerunabhängig, etc.) machen und für die Puffergröße kein Zahlenliteral ablegen, sondern die "richtige" Größe für den Puffer berechnen lassen. Prinzipiell ginge das dann so:

    Puffergröße = (int) ( ceil( log10( (double) ULLONG_MAX ) / log10( (double) Base ) ) ) + 2

    Im Detail:
    -> log10( ULLONG_MAX ) berechnet die Anzahl der Dezimalstellen der Zahl in der Zahlenbasis Base (noch als double mit Nachkommastellen),
    -> ceil() rundet diese zur Ganzzahl auf und
    -> + 2 schafft zusätzlichen Platz für ein Vorzeichen und den Terminator \0

    Leider, leider mault der Compiler beim Versuch den Puffer via

    static char TempInitBuf[(int) (ceil( log10( (double) ULLONG_MAX ) ) ) + 2];

    zu instanziieren jedoch mit einem

    error C2057: Konstanter Ausdruck erwartet

    und das verstehe ich nicht so ganz, denn obiger Ausdruck ist konstant und wäre durchaus zur Compilezeit berechenbar!

    Ich vermute aber mal, der MS-Compiler ist zu hohl zu blicken, dass auch doubles Konstanten sein können, denn:

    static const int MaxDez = 22;
    static char TempInitBuf[MaxDez]; // OK!

    static const double MaxDez = 22.0;
    static char TempInitBuf[(int) MaxDez]; // C2057!!


    Wie kann man das jetzt anders lösen? Any ideas? Mir fällt nur noch die wesentlich unportablere Möglichkeit über ein (hardcodiertes)

    #define MAXDEZ 22


    ein.

  • #2
    http://support.microsoft.com/kb/142493/de
    Christian

    Comment


    • #3
      Hi!

      Originally posted by Christian Marquardt View Post
      Habe mir den (gruselig übersetzten) Artikel mal angeschaut und dann lieber auf englisch gelesen. ;-)

      Leider löst das aber das Problem nicht, denn sobald der Ausdruck minimal komplizierter wird (i.e. im Ausdruck ein Funktionsaufruf mit einer Konstanten erfolgt), ist das Problem wieder da, egal ob define oder nicht. Bereits ein

      #define D_MAX log(5.55)
      int arr[(const int) D_MAX];

      macht's schon kaputt :-/

      Auch wenn man alles nach const castet, es nutzt nichts:

      #define Dez static_cast<const int>(ceil(log10(static_cast<const float>(ULLONG_MAX)) / log10(static_cast<const float>(10)))) + 2;
      static char TempBuf[(const int) Dez]; // C2057

      Im Prinzip ist dieses Verhalten auch absolut verständlich und richtig, denn:
      - Im M$-Beispiel wird die const Variable durch ein define ersetzt, d.h. durch eine typenlose(!) Zahl, die dann nach int gecastet wird. Hier aber wird via define ein Ausdruck definiert, und der ist durchaus von einen bestimmten Typ. Ob ich diesen Ausdruck nun direkt als Argument für das Array verwende oder ihn via define reinpfriemel, macht für den Compiler keinerlei Unterschied, denn der bekommt das alles erst zu sehen, wenn der Präprozessor schon seine Arbeit getan hat - im Klartext: der Comiler sieht in beiden Fällen *exakt* das Gleiche!
      - Der Compiler darf im Prinzip in einer Initialisierung gar keinen Funktionsaufruf zulassen, denn wo steht denn, dass die Funktion für einen bestimmten konstanten Eingangsparameter einen genau definierten Rückgabewert zu liefern hätte??!?!:

      int HowLargeAmI[rand()]; // Wie groß ist denn dieses Array, hm?!?!?

      Heißt also ganz eindeutig, es *kann und darf* so nicht gehen. Die Frage war nur, gibt es noch eine andere Möglichkeit als ein stumpfes #define Dez 22??


      Anbei bemerkt ist es schon oberpeinlich, dass M$ seit Version C++ 4.0 wissentlich einen Fehler mitschleift, der auch in der letzten Compilerversion noch vorhanden ist - mittlerweile sind wir bei Version 8.0... Immerhin ist diese letzte Version soweit ANSI-konform, dass man halbwegs vernünftig damit arbeiten kann...

      Cheerz

      Don

      Comment


      • #4
        Da wird dir dannwohl nurt dein define bleiben. Der Borland mag das übrigens auch nicht....
        Christian

        Comment

        Working...
        X