Intereting Posts

Это нормально для int ** и const int ** для псевдонима?

Я понимаю, что что-то вроде этого в порядке:

const int ci = 42; const int *cip = &ci; int *ip = (int *)cip; int j = *ip; 

Как насчет этого?

 const int ci = 42; const int *cip = &ci; const int **cipp = &cip; int **ipp = (int **)cipp; int j = **ipp; 

Выражение *ipp является lvalue типа int * , однако оно используется для доступа к объекту эффективного типа const int * . (А именно, cip ).

Согласно букве стандарта, это строгое нарушение псевдонимов: список разрешенных типов для псевдонима не включает псевдонимы T * как const T * или наоборот.

Наиболее близким исключением является следующее: (C11 6.5 / 6 отрывок)

  • квалифицированная версия типа, совместимая с эффективным типом объекта

«квалифицированная версия» четко определена C11 6.2.5 / 26:

Каждый неквалифицированный тип имеет несколько квалифицированных версий своего типа, соответствующих комбинациям одного, двух или всех трех независимых, volatile и restrict квалификаторов. Квалифицированные или неквалифицированные версии типа являются отдельными типами, относящимися к одной и той же категории, и имеют те же требования к представлению и выравниванию. Производный тип не определяется квалификаторами (если они есть) того типа, из которого он получен.

Таким образом, исключение состоит в том, что T может быть псевдонимом как const T и наоборот, но аналогичного исключения для указателей на алиативные типы не существует. const T * не является квалифицированной версией T * .


Однако есть, конечно, сноска:

objective этого списка – указать те обстоятельства, при которых объект может быть или не быть псевдонимом

Я не мог сказать, является ли намерение правила равным const T * и T * или нет. Мне кажется непонятным, какая цель указать, что T * и const T * имеют «те же требования к представлению и выравниванию» (6.2.5 / 28), если они не являются алиасируемыми.