Что означает const указатель на указатель в C и C ++? - PullRequest
41 голосов
/ 03 декабря 2008

Я знаю эмпирическое правило для чтения объявлений справа налево, и я был совершенно уверен, что знаю, что происходит, пока коллега не сказал мне, что:

const MyStructure** ppMyStruct;

означает, что «ppMyStruct является указателем на константный указатель на (изменяемый) MyStructure » (на C ++).

Я бы подумал, что это означает "ppMyStruct - это указатель на указатель на const MyStructure ". Я искал ответ в спецификации C ++, но, видимо, я не очень хорош в этом ...

Что означает в C ++ и означает ли это то же самое в C?

Ответы [ 7 ]

62 голосов
/ 03 декабря 2008

Ваш коллега не прав. Это (неконстантный) указатель на (неконстантный) указатель на константную MyStructure. На обоих языках C и C ++.

60 голосов
/ 03 декабря 2008

В таких случаях может пригодиться инструмент cdecl (или c ++ decl):

     [flolo@titan ~]$ cdecl explain "const struct s** ppMyStruct"
     declare ppMyStruct as pointer to pointer to const struct s
19 голосов
/ 03 декабря 2008

Вы были правы в своей интерпретации. Вот еще один способ взглянуть на это:

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

Это все альтернативы указателя на указатель с одним константным квалификатором. Правило справа налево может использоваться для расшифровки объявлений (по крайней мере, в C ++; я не эксперт C).

5 голосов
/ 03 декабря 2008

Вы правы.

Другой ответ уже указывал на " Правило спирали по часовой стрелке ". Мне он очень понравился - хотя и немного сложный.

5 голосов
/ 03 декабря 2008

Ваш коллега не прав, и то же самое для C и C ++. Попробуйте следующее:

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 дает следующие ошибки для последних двух строк:

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

GCC 4 говорит:

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

G ++ 4 говорит:

error: assignment of data-member 'foo_t::i' in read-only structure
error: assignment of data-member 'foo_t::i' in read-only structure
3 голосов
/ 03 декабря 2008

Как следствие других комментариев, не ставьте «const» первым. Это действительно принадлежит после типа. Это сразу бы прояснило смысл, просто прочитайте RTL как обычно:

MyStructure const** ppMyStruct;
0 голосов
/ 06 февраля 2010
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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...