irres Konstrukt und merkwürdiger Compilerfehler



  • Hallo erstmal!

    Ich habe seid gestern ein Problem mit dem folgenden Konstrukt.

    IF_RC
    IF_QueryDBServerData (IF_HANDLE            PV_IfHandle,
                          int                 *PV_NumberDBServerData,
                          const char *const (**PV_DBServerData)[]);
    

    Als Prozedur läßt es sich mit dem GCC in C wunderbar compilieren. Als C++-Methode in einer Klasse wiederrum nicht. Rufe ich den GCC auf, erscheint die folgende Fehlermeldung.

    > gcc -c DCDConnect.cpp
    In file included from DCDConnect.cpp:1:
    DCDConnect.h:17: error: parameter `PV_DBServerData' includes pointer to array
       of unknown bound `const char* const[]'
    

    Wenn ich aber die Methode ihren Argumenten nach in einer Klasse definiere, ohne die Methode an sich zu definieren, wird alles sauber compiliert. Laut der Fehlermeldung ist auch das dritte Argument der Schuldige. Zu meiner Schande muss ich gestehen, dass ich das Konstrukt

    const char *const (**PV_DBServerData)[]
    

    auch nicht ganz verstehe. Erschwerend hinzu kommt, dass die Prozedur zu einer API gehört, auf die ich zugreifen muss. Somit muss ich den gcc irgendwie überreden dies auch in C++ zu compilieren. Vielleicht könnt ihr mir ja helfen. Danke schonmal im voraus.



  • Hallo,

    kann Dir leider nur sagen, dass es mit dem Studio 2003 kompiliert.

    Mich würde auch interessieren was der Parameter bedeutet.
    In Worten wäre meine Interpretaion
    Ein Zeiger auf ein Array von Zeigern auf Zeigern ???

    Kommt das hin? Ist das Standardkonform?



  • templäd schrieb:

    Mich würde auch interessieren was der Parameter bedeutet.
    In Worten wäre meine Interpretaion
    Ein Zeiger auf ein Array von Zeigern auf Zeigern ???

    Nein, ein Zeiger auf einen Zeiger auf ein Array (unbestimmter Größe) von Zeigern. Ob das in C++ erlaubt ist (genauer gesagt: ob man Zeiger auf Arrays unbestimmer Größe haben kann, oder ob das nur mit VLAs ala C99 geht) weiß ich nicht genau.



  • Bashar schrieb:

    Nein, ein Zeiger auf einen Zeiger auf ein Array (unbestimmter Größe) von Zeigern. Ob das in C++ erlaubt ist (genauer gesagt: ob man Zeiger auf Arrays unbestimmer Größe haben kann, oder ob das nur mit VLAs ala C99 geht) weiß ich nicht genau.

    So sehe ich das mittlerweile auch. Es ist übrigens ein Zeiger-auf-Konstante-Konstrukt, wobei der Zeiger selbst auch konstant ist. Nun habe ich auch schon die Man des GCC studiert, konnte aber nichts finden, um das Probelm zu lösen. Auch die Anweisung, dass gcc es als C (über __cplusplus) handhaben soll, hat nichts gebracht.

    Ich werde jetzt erstmal Feierabend machen und mich morgen wieder damit rumschlagen.


  • Mod

    soweit ich es verstehe ist diese form in C++ explizit ausgeschlossen (8.3.5/6). es ist zu vermuten, dass du den parameter auch einfach als

    const char *const (**PV_DBServerData)
    

    ohne negative auswirkungen schreiben kannst (unterschiede ergäben sich nur in der funktionsdefinition).



  • So ist es doch nur noch nen Zeiger auf nen Zeiger auf nen konstanten Zeiger auf eine konstante Zeichenkette statt einem Zeiger auf nen Zeiger auf nen Array aus konstanten Zeiger auf eine konstante Zeichenkette.



  • Wenn aus dem Array ein Pointer wird, dann müßte es doch

    const char *const (***PV_DBServerData)
    

    heißen, oder? Die Implementierung müßte eigentlich genauso wie vorher aussehen können.


  • Mod

    Jester schrieb:

    Wenn aus dem Array ein Pointer wird, dann müßte es doch

    const char *const (***PV_DBServerData)
    

    heißen, oder? Die Implementierung müßte eigentlich genauso wie vorher aussehen können.

    ich denke nicht.
    ein ausdruck **PV_DBServerData würde (mit der ursprünglichen deklaration, wenn sie denn in C++ legal wäre) ein lvalue array unbekannter größe sein (auf jeden fall ist es keine pointer auf einen konstanten pointer auf konstantes char - und da da das array unbekannte größe hat, kann man hier in der zweiten ebene eben nur * und keinen index-zugriff durchführen. der einzige weg, diesen ausdruck weiterzuverwenden, ist dann den index-operator zu benutzen:
    (**PV_DB_ServerData)[x]
    Das ergebnis ist dann eine konstanter zeiger auf einen konstanten string.


    *(&a[0] + x) bzw. *(a + x)
    also

    netto also nur zwei indirektionen

    !--------------------------------------------------------------------------------------!
    !const char* const (0)!const char* const (1)!const char* const (2)!const char* const (3)! ...
    !--------------------------------------------------------------------------------------!
    
      / \
       |
       |
    const char* const(*)[]
    
      / \
       |
       |
    const char* const(**)[]
    

    und damit ändert sich der code in der funktionsdefinition: statt zweier * operatoren, braucht man nur noch einen im obersten level, der zweite verschmilzt mit dem indexoperator.



  • Moin,

    eine Änderung an dem Header-File wollte ich eigentlich vermeiden, da ich dieses nicht verbockt habe. Hier im Büro wurde auch schon die Holzhammermethode vorgeschlagen, in dem ich einfach das Argument als void-Zeiger deklariere, aber wie gesagt, ich möchte das Header-File nur ungern ändern. Ich werde jetzt eine Dummy-Bibliothek in C schreiben, die ich dann unter C++ ohne große Problem compilieren kann. Dieser Weg ist zwar nicht schön, aber selten. 😉


Anmelden zum Antworten