, gcc и clang следует рассматривать как обработку диалекта C, в котором эффективные типы, когда они установлены, становятся постоянными. Они не могут надежно распознать все случаи, когда эффективные типы могут быть изменены, и логика, необходимая для обработки, которая могла бы легко и эффективно обрабатывать многие случаи, о которых авторы gcc уже давно заявляли, не может быть обработана без потрошения оптимизации.

оложим, у меня есть кусок динамически распределенных данных:

void* allocate (size_t n)
{
  void* foo = malloc(n);
  ...
  return foo;
}

Я хочу использовать данные, на которые указываетfoo как особый тип,type_t, Но я хочу сделать это позже, а не во время распределения. Для того, чтобы дать выделенным даннымэффективный типПоэтому я могу сделать что-то вроде:

void* allocate (size_t n)
{
  void* foo = malloc(n);
  (void) *(type_t*)foo;
  ...
  return foo
}

Согласно C11 6.5 / 6, этот доступ к lvalue должен сделать эффективный типtype_t:

Для всех других обращений к объекту, у которого нет объявленного типа, эффективный тип объекта - это просто тип lvalue, используемого для доступа.

Тем не менее, линия(void) *(type_t*)foo; не содержит побочных эффектов, поэтому компилятор должен иметь возможность оптимизировать его, и я не ожидал бы, что он сгенерирует какой-либо фактический машинный код.

Мой вопрос: безопасны ли уловки, подобные вышеописанным? Считает ли предоставление данных эффективный тип побочным эффектом? Или, оптимизируя код, компилятор также оптимизирует выбор эффективного типа?

То есть, с помощью описанного выше трюка доступа lvalue, если я сейчас вызываю вышеуказанную функцию следующим образом:

int* i = allocate(sizeof(int));
*i = something;

Вызывает ли это строгое нарушение псевдонимов UB, как ожидается, или является эффективным типом сейчасint?

Ответы на вопрос(2)

Ваш ответ на вопрос