Was bedeutet ein konstanter Zeiger-zu-Zeiger in C und in C++?

Lesezeit: 4 Minuten

Benutzeravatar von Niklas
Niklas

Ich kenne die Faustregel, Erklärungen von rechts nach links zu lesen, und ich war mir ziemlich sicher, dass ich wusste, was vor sich ging, bis mir ein Kollege sagte:

const MyStructure** ppMyStruct;

bedeutet “ppMyStruct ist ein Zeiger auf einen konstanten Zeiger auf eine (veränderliche) MyStructure” (in C++).

Ich hätte gedacht, es bedeutet “ppMyStruct is ein Zeiger auf einen Zeiger auf eine const MyStructure“. Ich habe in der C++-Spezifikation nach einer Antwort gesucht, aber anscheinend bin ich nicht sehr gut darin …

Was bedeutet in in C++ und bedeutet es dasselbe in C?

Dein Kollege liegt falsch. Das ist ein (nicht konstanter) Zeiger auf einen (nicht konstanten) Zeiger auf eine konstante MyStructure. Sowohl in C als auch in C++.

  • Dies ist auch einer der Gründe, warum Sie manchmal die alternative „Schreibweise empfohlen“ sehen: MyStructure const * *ppMyStruct; Dann können Sie von rechts nach links lesen: Zeiger auf Zeiger auf const MeineStruktur.

    – Joris Timmermans

    3. Dezember 2008 um 14:00 Uhr

  • Wer liest RTL? Sicherlich keiner meiner Kunden 🙂 Ich denke, wir brauchen keine RTL-Unterstützung, oder?

    – dom0

    27. Juli 2013 um 19:14 Uhr

  • Dies ist ein alter Beitrag, daher wird meine Kommentarfrage wahrscheinlich nicht beantwortet: Wie erstelle ich einen konstanten Zeiger auf einen konstanten Zeiger auf eine konstante MyStructure?

    – tchronis

    31. Januar 2015 um 15:22 Uhr

  • @tchronis, ich habe es nicht getestet (nur dass es kompiliert), aber versuche so etwas wie: MyStructure const * const * const ptrMyStr;

    – Javier Mr

    28. April 2015 um 7:01 Uhr

In solchen Fällen kann das Tool cdecl (oder c++decl) hilfreich sein:

     [flolo@titan ~]$ cdecl explain "const struct s** ppMyStruct"
     declare ppMyStruct as pointer to pointer to const struct s

  • Sehr hilfreich. Warum ist dieses Tool nicht bekannt?

    – David Holm

    3. Dezember 2008 um 10:59 Uhr

  • Weißt du zufällig, ob es das für Windows gibt?

    – Niklas

    3. Dezember 2008 um 11:03 Uhr

  • Es ist Open Source und hat keine besonderen Anforderungen an das Betriebssystem. Wenn Sie Glück haben, sollte es mit jedem Compiler kompilierbar sein, im schlimmsten Fall müssen Sie das gcc/cygwin- oder mingw-Zeug verwenden.

    – flolo

    3. Dezember 2008 um 11:13 Uhr

  • @flolo du bist ein Held! Ich habe noch nie von diesem Tool gehört! Danke, dass du es geteilt hast! +1

    – DJJ

    6. März 2020 um 3:01 Uhr

  • Online-Version unter cdecl.org Funktioniert auch umgekehrt! Geben Sie das Englisch ein, erhalten Sie den Code.

    – Ameise

    29. Juni 2020 um 10:21 Uhr


Du hattest Recht mit deiner Interpretation. Hier ist eine andere Möglichkeit, es zu betrachten:

const MyStructure *      *ppMyStruct;        // ptr --> ptr --> const MyStructure
      MyStructure *const *ppMyStruct;        // ptr --> const ptr --> MyStructure
      MyStructure *      *const ppMyStruct;  // const ptr --> ptr --> MyStructure

Dies sind alle Alternativen eines Pointer-to-Pointer mit einem konstanten Qualifizierer. Die Rechts-nach-Links-Regel kann verwendet werden, um die Deklarationen zu entschlüsseln (zumindest in C++; ich bin kein C-Experte).

  • Was ist mit MyStructure const* *ppMyStruct;?

    – tobi

    19. Januar 2013 um 20:56 Uhr

  • @tobi, das ist das gleiche wie die erste Zeile. Siehe stackoverflow.com/q/3694630 (sie sprechen von Referenzen, aber Zeiger verhalten sich gleich).

    – efotinis

    20. Januar 2013 um 15:35 Uhr

Benutzeravatar von csl
csl

Ihr Kollege liegt falsch, und es ist dasselbe für C und C++. Versuche Folgendes:

typedef struct foo_t {
    int i;
} foo_t;

int main()
{
    foo_t f = {123};
    const foo_t *p = &f;
    const foo_t **pp = &p;
    printf("f.i = %d\n", (*pp)->i);
    (*pp)->i = 888; // error
    p->i = 999;     // error
}

Visual C++ 2008 gibt die folgenden Fehler für die letzten beiden Zeilen aus:

error C2166: l-value specifies const object
error C2166: l-value specifies const object

GCC4 sagt:

error: assignment of read-only location '**pp'
error: assignment of read-only location '*p'

G++4 sagt:

error: assignment of data-member 'foo_t::i' in read-only structure
error: assignment of data-member 'foo_t::i' in read-only structure

Benutzeravatar von xtofl
xtofl

Du sind richtig.

Eine andere Antwort wies bereits auf die “Spiralregel im Uhrzeigersinn“. Das hat mir sehr gut gefallen – wenn auch etwas aufwendig.

Benutzeravatar von MSalters
MSalter

Setzen Sie als Folge der anderen Kommentare nicht “const” an die erste Stelle. Es gehört wirklich nach dem Typ. Das hätte die Bedeutung sofort verdeutlicht, einfach wie gewohnt bei RTL lesen:

MyStructure const** ppMyStruct;

void Foo( int       *       ptr,
          int const *       ptrToConst,
          int       * const constPtr,
          int const * const constPtrToConst )
{
    *ptr = 0; // OK: modifies the pointee
    ptr  = 0; // OK: modifies the pointer

    *ptrToConst = 0; // Error! Cannot modify the pointee
    ptrToConst  = 0; // OK: modifies the pointer

    *constPtr = 0; // OK: modifies the pointee
    constPtr  = 0; // Error! Cannot modify the pointer

    *constPtrToConst = 0; // Error! Cannot modify the pointee
    constPtrToConst  = 0; // Error! Cannot modify the pointer
}

  • Ich verstehe nicht, wie dies eine Antwort auf die Frage sein soll. Hast du es falsch gelesen?

    – Niklas

    6. Februar 2010 um 8:14 Uhr

1401570cookie-checkWas bedeutet ein konstanter Zeiger-zu-Zeiger in C und in C++?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy