Предупреждение о множественных несогласованных изменениях, не примененных к элементам структуры

#c

#c

Вопрос:

Я обнаружил любопытное исключение из предупреждения о множественных непоследовательных модификациях. Я столкнулся с предупреждением при циклическом преобразовании счетчика:

 int i = 0;
i =   i amp; 0xFF; // <- warning
  

предупреждение: множественные непоследовательные модификации ‘i’

Я понимаю, почему это неопределенное поведение. Однако я обнаружил, что это предупреждение не применяется при использовании членов структуры:

 typedef struct
{
    int i;
}struct_t;

struct_t t;
t.i =   t.i amp; 0xFF; // <- no warning
  

То же самое относится и к указателям:

 struct_t *u;
u = amp;t;
u->i =   u->i amp; 0xFF; // <- no warning
  

Я использую MDK-ARM Plus версии 5.21a в режиме C99.

Мой вопрос заключается в том, действительно ли это приемлемый код, что по какой-то причине, поскольку я использую структуры, это больше не неопределенное поведение, или предупреждения компилятора просто пропускают его.

Комментарии:

1. Это все еще UB, компилятор, похоже, просто не улавливает его.

2. Там уже есть тонны этих вопросов. Все это UB.

3. Другой компилятор выдает предупреждение: ideone.com/jYr2vn

4. Возможно, это часто задаваемые вопросы, но я думаю, что это отличное использование SO, чтобы спросить здесь, прежде чем отправлять отчет об ошибке поставщику компилятора. Избавляет вас от затруднений, если вы ошибаетесь, избавляет поставщика компилятора от некоторых раздражающих поручений службы поддержки и предупреждает других программистов о компиляторах с ошибками. Выигрывают все, кроме производителей компиляторов с ошибками.

Ответ №1:

Ваши два примера идентичны в том, что касается точек последовательности. Оба они вызывают неопределенное поведение (согласно 6.5), поскольку i изменяются дважды в одном и том же выражении без промежуточной точки последовательности. Тип данных i не имеет значения, и не имеет значения, является ли он частью структуры.

Это неприемлемый код. Однако компилятор не обязан предоставлять вам диагностику для кода, который вызывает неопределенное поведение. Если вы его получите, то это ужасно мило со стороны компилятора.

Причина, по которой ваш компилятор непоследователен в своих предупреждениях, по-видимому, заключается в незначительной ошибке компилятора.