Почему нет предупреждения из-за перезаписи членов профсоюза в gcc? - PullRequest
0 голосов
/ 28 сентября 2018

Предполагая этот фрагмент кода в файле file.c:

union numbers
  {
     int i;
     float f;
  };

union numbers first_number;

first_number.i = 5;
first_number.f = 3.9;

printf("%i %'.2f\n", first_number.i, first_number.f);

Почему нет предупреждения о том, что first_number.i перезаписывается после компиляции с gcc -Wall file.c и где получается результирующее число first_number.iидет от?

По крайней мере, какова общая цель перезаписи членов объединения, не лучше ли объявлять больше переменных объединения, чтобы избежать такого поведения?

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Используется для экономии места (памяти), когда вам нужны разные поля в разное время.

Нет дополнительного места для записи, какое поле объединения было записано последним.И поэтому нет способа автоматически обнаружить чтение «неправильного» поля при запуске программы.Программист должен сделать это сам.И в большинстве случаев компилятор также не может обнаружить такие операции чтения.

Но даже в тех случаях, когда может обнаружить, GCC не предупреждает об этом.Почему?

Это потому, что программисты на C иногда делают хотят интерпретировать тип A в памяти как тип B. Мы странные, как это.

GCC явно документируетчто вы можете повторно интерпретировать типы - если вы используете объединение.Как и другие крупные компиляторы.Существует некоторая путаница в том, удалось ли всем официальным стандартам С правильно определить это правило.Но все согласны с тем, что это правило на практике.

https://blog.regehr.org/archives/1307#comment-18418

https://stackoverflow.com/questions/11373203/accessing-inactive-union-member-and-undefined-behavior

Вы можете подумать, что вы можете использовать приведение указателей вместо объединения.Ты был бы неправ.Это поведение "неопределено" стандартом.Компилятор может обработать любой путь кода, где это могло бы произойти, как невозможное, и игнорировать его.Тогда может произойти все, что угодно .Этот процесс известен как «оптимизация».

https://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html

Пользователям рекомендуется не слишком задумываться о том, что это значит, если вы начнете жонглировать указателями на различные поля объединения, и простоубедитесь, что они никогда этого не делают.https://stackoverflow.com/questions/11639947/is-type-punning-through-a-union-unspecified-in-c99-and-has-it-become-specified#comment61928962_11640381

Пользователи C ++ должны использовать reinterpret_cast<>.Также утверждается, что стандартный C ++ не поддерживает повторную интерпретацию типов с union.

0 голосов
/ 28 сентября 2018

Вот так работают профсоюзы.Если вы хотите неперекрывающиеся поля, используйте структуру.Значение элемента .i после сохранения значения с плавающей запятой - это битовая комбинация, интерпретируемая как int.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...