Как объявить постоянный изменяемый указатель на неизменяемый блок памяти

Мне интересно, как объявить, в основном, (a const pointer to (a mutable pointer to (a const type))) в C99.

Скажем, у меня есть этот сайт вызова:

const uint8_t* result;
create(&result);

Является ли void create(const uint8_t * const * resultPtr) правильным способом объявления вызываемого объекта в этом случае или это означает что-то непреднамеренное? Мне не нужно переназначать resultPtr, и вызывающая сторона не должна возиться с [с этой точки зрения] *resultPtr[0], но моя функция должна назначать *resultPtr = ….


person natevw    schedule 29.09.2014    source источник


Ответы (2)


Давайте спросим cdecl:

$ cdecl declare p as const pointer to pointer to const char
const char ** const p

Это объявление можно прочитать полностью справа налево, чтобы получить английскую версию (помните, что const char и char const одинаковы).

person Fred Foo    schedule 29.09.2014
comment
О, я совсем забыл о cdecl. Спасибо большое! - person natevw; 30.09.2014
comment
К сожалению, сайт cdecl, кажется, пошел по пути всех вещей. :-( - person T.J. Crowder; 08.08.2020

Некоторые эмпирические правила:

  • <type> * const <varName> = <value> всегда создает неизменяемый указатель <varName> на содержимое <type>. Обратите внимание на const справа от звездочки * const.
  • all these options create immutable contents:
    • const <type> <pointers> <varName> = <value>
    • <type> const <pointers> <varName> = <value>
    • const <type> const <pointers> <varName> = <value>
    • <type> const const <pointers> <varName> = <value>

Предостережение: последние два параметра возвращают

предупреждение: повторяющийся спецификатор объявления 'const' [-Wduplicate-decl-specifier]

на компиляторе Clang и должно рассматриваться как плохая практика.

Таким образом, чтобы иметь неизменяемый указатель на изменяемый указатель на неизменяемый uint8_t, все эти варианты работают:

  • const uint8_t * * const result = NULL
  • uint8_t const * * const result = NULL
  • const uint8_t const * * const result = NULL
  • uint8_t const const * * const result = NULL

Однако второй вариант

uint8_t const * * const result = NULL;

кажется, это самый читаемый и канонический способ написать это ИМХО. Вы можете найти этот пост также информативным в этом отношении.

person Foad    schedule 07.02.2020