Является ли приведение неполных структурных указателей неопределенным поведением? - PullRequest
0 голосов
/ 26 декабря 2018

В настоящее время я читал о некоторых строгих правилах псевдонимов, и мне было интересно, является ли приведение указателя на неполную структуру неопределенным поведением.

Пример 1 :

#include <stdlib.h>

struct abc;

int main(int argc, char *argv[])
{
  struct abc *mystruct;
  char *buf;

  buf = malloc(100);
  mystruct = (struct abc*)buf;

  // and then mystruct could be submitted to a function, where it is
  // casted back to a "char *", the "struct abc" will never be completed.

  return 0;
}

Пример 2 :

struct abc1;
struct abc2;

int foo(struct abc1 *mystruct1)
{
  struct abc2 *mystruct2;

  mystruct2 = (struct abc2 *)mystruct1;

  // and then mystruct2 could be submitted to a function, where it is
  // casted to a "char *", both structs stay incomplete.

  return 0;
}

Итак, мой вопрос: приведение указателей к неполным структурам, как в этих двух примерах, запрещено стандартом c11, и если да, то какая частьстандарт запрещает это?

1 Ответ

0 голосов
/ 26 декабря 2018

Одной ключевой соответствующей частью стандарта является C11 §6.2.5 Типы ¶28 :

28 Указатель на void должен иметь те же требования к представлению и выравниванию, что иуказатель на тип символа. 48) Аналогично, указатели на квалифицированные или неквалифицированные версии совместимых типов должны иметь одинаковые требования к представлению и выравниванию.Все указатели на типы конструкций должны иметь те же требования к представлению и выравниванию, что и другие.Все указатели на типы объединения должны иметь те же требования к представлению и выравниванию, что и другие.Указатели на другие типы не обязательно должны иметь одинаковые требования к представлению или выравниванию.

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

Другой - §6.3 Преобразования и особенно §6.3.2.3 Указатели ¶7 :

7Указатель на тип объекта может быть преобразован в указатель на другой тип объекта.Если полученный указатель неправильно выровнен 68) для ссылочного типа, поведение не определено.В противном случае при обратном преобразовании результат сравнивается равным исходному указателю.Когда указатель на объект преобразуется в указатель на тип символа, результат указывает на младший адресуемый байт объекта.Последовательные приращения результата, вплоть до размера объекта, дают указатели на оставшиеся байты объекта.

68) В общем, понятие «правильно выровненное» имеет видпереходный: если указатель на тип A правильно выровнен для указателя на тип B, который в свою очередь правильно выровнен для указателя на тип C, то указатель на тип A будет правильно выровнен для указателя на тип C.

Таким образом, я понимаю, что нет проблем с фрагментом кода, приведенным в вопросе.Типы структур неполные, но это не проблема для показанных операций.Разделы «и потом» в коде не должны быть проблематичными - это зависит от того, что на самом деле там.

...