konstante Elemente in Struktur



  • wieso können MSVC und GNUC(da lief es jetzt jahrelang) das und der BCB gibt die Fehler?

    [C++ Fehler] Unit1.cpp(36): E2232 Konstante-Element 'MENUE_VAR_TYP::ADRESSE' in Klasse ohne Konstruktoren
    [C++ Fehler] Unit1.cpp(36): E2232 Konstante-Element 'MENUE_VAR_TYP::test_funktion' in Klasse ohne Konstruktoren
    ??

    enum TEST_FUNKTION_VAR
    {
      QWE,
      RTZ,
      ZUI,
    };
    
    struct MENUE_VAR_TYP
    {
      unsigned char XPOS;
      unsigned char YPOS;
      const void* const ADRESSE;
      unsigned char INDEX;
      unsigned char MAX_FELD;
      void (* const test_funktion)(TEST_FUNKTION_VAR komplett);
    };
    
    const MENUE_VAR_TYP foo[] =
    {
      {1, 2, 0, 0, 0, 0}
    };
    

    Der Fehler scheint mir mit der stuctdeklaration ein wenig verfrüht zu kommen da er doch noch garnich weiss wie ich die Dinger deklariere =[ .

    [ Dieser Beitrag wurde am 19.03.2003 um 12:10 Uhr von dreaddy editiert. ]



  • was ist das denn bitteschön??? const xxx const???

    const void* const ADRESSE;
    
    // probiers mal hiermit
    struct MENUE_VAR_TYP
    {
      unsigned char XPOS;
      unsigned char YPOS;
      const void *ADRESSE;
      unsigned char INDEX;
      unsigned char MAX_FELD;
      const void (*test_funktion) (TEST_FUNKTION_VAR komplett);
    };
    

    [ Dieser Beitrag wurde am 19.03.2003 um 15:13 Uhr von Sunday editiert. ]



  • naja du kannst bei pointern 2 Sachen konst machen...
    Einmal den Zeiger ansich und einmal den Inhalt.

    sprich beim einen const geht
    zeiger = 0x234234; nicht
    und beim andern geht
    *zeiger = 123;
    nicht

    Das es geht wenn das zweite const weg ist ist mir klar 😃 aber leider muss ich alten Programmcode nehmen und wenn ich das weglassen würde müsste ich abgesehen von der wegfallenden Sicherheit so um die 20000 Programmzeilen ändern

    [ Dieser Beitrag wurde am 19.03.2003 um 16:30 Uhr von dreaddy editiert. ]



  • Ich verschieb das mal nach "C++", um zu klären, ob hier dein Code/MSVC/GNUC oder der BCB vom Standard abweichen.

    Anbei noch der entsprechende Eintrag aus der Borland-Hilfe:

    Eine Klasse, die konstante oder Referenzelemente (oder beides) enthält, muß mindestens einen benutzerdefinierten Konstruktor haben.

    Ansonsten gäbe es keine Möglichkeit, solche Elemente zu initialisieren.



  • Du kannst den constpointer nur in in der Elementinitalisierungsliste eines Konstruktors initalisieren. Anders gehts nicht.



  • DOCH 😑

    also den GNUC Compiler halte ich mal für den am meisten am Standard orientierten und auf dem läuft obiger Code seit Jahren.
    Und selbst der Visual C++ bekommt das hin.

    Ich initialisier den ja beim konstruieren:

    const MENUE_VAR_TYP foo[] =
    {
      {1, 2, 0, 0, 0, 0}
    };
    

    Aber der BCB meckert schon bei der Klassendeklaration rum bevor ich überhaupt ein Objekt des typs angelegt habe.

    [ Dieser Beitrag wurde am 20.03.2003 um 08:25 Uhr von dreaddy editiert. ]



  • Im neuen C Standard gibs doch diese Art der Initalisierung:
    typedef struct _TAGfoo
    {
    const void* const bar;
    } FOO;

    FOO foo = { .bar = 0 }

    Probiers mal mit dem Comeauo-Online-Compiler (Wie wird der geschrieben?)



  • jo habich noch in Favoriten, gute Idee

    also der meint

    Comeau C/C++ 4.3.1 (Mar  1 2003 20:09:34) for ONLINE_EVALUATION_BETA1
    Copyright 1988-2003 Comeau Computing.  All rights reserved.
    MODE:strict errors C++
    
    "ComeauTest.c", line 8: warning: class "MENUE_VAR_TYP" defines no constructor to
              initialize the following:
                const member "MENUE_VAR_TYP::ADRESSE"
                const member "MENUE_VAR_TYP::test_funktion"
      struct MENUE_VAR_TYP
             ^
    
    "ComeauTest.c", line 18: warning: variable "foo" was declared but never referenced
      const MENUE_VAR_TYP foo[] =
                          ^
    
    In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link).
    

    Die Warnung ok, aeber sollte doch gehen



  • Ich weiss nicht, aber gibt es denn const-pointer als struct-Element im C Standard? kA



  • naja ich hab ja als c++ compiliert,
    den "ComeauTest.c" namen wird er nur immer machen.

    Der Hintergrund für diesen ganzen const kram ist das er Tabellen in das ROM packt auf unsrer embedded Kiste, aber das ändert nix an der Sache das es Standard is.

    oh und ganz vergesse ^^
    link war http://www.comeaucomputing.com/tryitout/

    [ Dieser Beitrag wurde am 20.03.2003 um 08:56 Uhr von dreaddy editiert. ]



  • Original erstellt von dreaddy:
    **naja ich hab ja als c++ compiliert,
    **

    Und in C++ kann man constante Elemente nur in der Elementinitalisierungsliste initalisieren.



  • Hm ich würde auch mal darauf tippen das Du den Konstruktor schreiben musst.

    const T * const t;

    soll ja verhindern das an dem Zeiger irgendwas gedreht werden kann.
    Sobald das NICHT per initialisieren passiert ist doch der sinn von dem const T* const weg ?!?

    const MENUE_VAR_TYP foo[] =
    {
      {1, 2, 0, 0, 0, 0}
    };
    

    Hier muss ich passen. Das sieht mir eher danach aus als sollten 6 MENUE_VAR_TYP in ein Array (foo) gepackt werden und nicht 1 mit initialisierung der Werte !?

    [ Dieser Beitrag wurde am 20.03.2003 um 09:13 Uhr von Knuddlbaer editiert. ]



  • Der kram WIRD initialisiert ^^ wieso kennt diese Weise keiner.
    Probiert dochmal folgenden Quellcode aus und lernt 😃 :

    struct bla
    {
      int wert1;
      char* wert2;
      char wert3;
    };
    
    bla blaarray[]=
    {
      {1, "hallo", 23},
      {2, "Welt", 34},
      {3, "kennt ihr mich?",45}
    };
    
    int main(void)
    {
      for(int i = 0; i< (sizeof(blaarray)/sizeof(bla));i++)
      {
        cout << blaarray[i].wert1<<". ";
        cout << blaarray[i].wert2<<" ";
        cout << blaarray[i].wert3<<" \n";
      }
    }
    

    oder ein vieleicht praktischeres Beispiel:

    #include <iostream>
    #include <conio>
    
    using std::cout;
    struct menu
    {
      int x;
      int y;
      const char* wert;
    };
    
    menu usermenu[]=
    {
      {10, 3, "Userverwaltung"},
      {2, 5, "1. Useruebersicht"},
      {2, 6, "2. User anlegen"},
      {2, 7, "3. User loeschen"},
      {2, 8, "----------------"},
      {2, 10, "4. User befoerdern"},
      {2, 11, "4. User fuettern"},
      {2, 12, "5. User waschen"},
      {2, 13, "6. Attentaeter anfordern"},
    };
    
    int main(int argc, char* argv[])
    {
      for(int i = 0; i< (sizeof(usermenu)/sizeof(menu));i++)
      {
        gotoxy(usermenu[i].x,usermenu[i].y);
        cout << usermenu[i].wert<<" \n";
      }
      getch();
      return 0;
    }
    //---------------------------------------------------------------------------
    

    und genau das geht auch mit Konstanten normalerweise also

    const char* const wert2
    

    , wo Borland aber nicht mitspielt

    *edit* syntaxfehler 😕

    [ Dieser Beitrag wurde am 20.03.2003 um 11:18 Uhr von dreaddy editiert. ]



  • du verwendest aber nicht die initialisierungsliste!

    der compiler macht daraus:

    const void* const p;
    p=foo;

    das geht nicht
    du musst p nunmal beim erstellen initialisieren
    und das geht nur mit der initialisierungsliste



  • und wo ist der Unterschied zwischen

    const char* const test = "hallo";
    

    (funktioniert)

    und

    struct zwei_charp
      {
        const char* const bla1;
        const char* const bla2;
      };
    
      zwei_charp = test {"hallo", "welt"};
    

    (funktioniert beim GNUC und VC aber nicht beim BCB)

    [ Dieser Beitrag wurde am 20.03.2003 um 11:25 Uhr von dreaddy editiert. ]



  • Da merkt man doch wie wenig man sich auskennt 🤡

    const char* const test = "hallo"; <- Zuweisung keine Initialisierung ?



  • Mir ist diese Arrayartige Initalisierung von structs neu. Gibts die im C++ oder/und C Standard?



  • const char* const test = "hallo";

    Das ist eine *Initialisierung*. Die Zeile ist legal.

    struct zwei_charp
    {
    const char* const bla1;
    const char* const bla2;
    };

    zwei_charp = test {"hallo", "welt"};

    Das müsste wenn überhaupt:

    struct zwei_charp
      {
        const char* const bla1;
        const char* const bla2;
      };
    
      zwei_charp test = {"hallo", "welt"};
    

    heißen. Der Code ist allerdings nicht legal. Wie man im C++ Standard Abschnitt 8.5.9 nachlesen kann. Eine Klasse mit const-Membern benötigt einen benutzerdefinierten Konstruktor. Hat eine Klasse erstmal einen solchen, ist die Initialisierung über eine brace-enclosed-intializer-list nicht mehr erlaubt.

    Mir ist diese Arrayartige Initalisierung von structs neu. Gibts die im C++ oder/und C Standard?

    Ja. Zu C kompatibel sind die sogenannten Aggregates = Array oder Klasse ohne bnutzerdefinierte Ctoren, ohne private/protected nonstatic Members, ohne Basisklassen und ohne virtuelle Funktionen.
    Relevante Regelen findest du in 8.5.1 und 12.6

    [ Dieser Beitrag wurde am 20.03.2003 um 13:22 Uhr von HumeSikkins editiert. ]



  • hm, vor Jahren hatten wir das anders gelöst und als dann der neue Standard (bzw eine neue Compilerversion mit diesem) rauskam lief es nicht mehr.
    Und nach etwas Forschung in den neuen Standards sind wir dann zu so einer Lösung gekommen.

    So sagt es der Historiker zu meiner Linken zumindest.

    [ Dieser Beitrag wurde am 20.03.2003 um 13:49 Uhr von dreaddy editiert. ]



  • Original erstellt von HumeSikkins:
    *[quote] const char const test = "hallo";
    **

    **
    Das ist eine *Initialisierung*. Die Zeile ist legal.
    **[/QUOTE]

    Ah jetzt ja! 🤡

    Danke schön!



  • Ok, danke Hume für die Mühe jetz ist eindeutig 😃 Kann man die Dinger eigentlich auch irgendwo im www nachlesen?

    Und ich hab mir das jetzt nochmal genauer angeschaut und festgesetellt das das zweite const wegfallen kann, daher gehts auch wieder mit beiden Compilern.

    Oh und bitte meine obige Antwort vor Humes denken, war etwas spät mit auf Antworten drücken.


Anmelden zum Antworten