Термин «С» используется для описания двух языков: один изобретенный K & R, в котором указатели идентификации местоположения физической памяти, и тот, который является производным от той, которая работает так же, в тех случаях, когда указатели либо чтения и написаны способами, которые соблюдают определенные правила, но могут вести себя произвольно, если они используются другими способами. Хотя последний язык определен стандартами, прежний язык стал популярным для программирования микрокомпьютеров в 1980-х годах.
Одним из основных препятствий для создания эффективного машинного кода из кода C является то, что компиляторы не могут определить, какие указатели могут использовать псевдонимы для переменных. Таким образом, любой временной код обращается к указателю, который может указывать на заданную переменную, генерируемый код необходим для обеспечения соответствия содержимого памяти, идентифицированного указателем и содержимым переменной. Это может быть очень дорого. Люди, пишущие стандарт C89, решили, что компиляторам следует разрешить предположить, что именованные переменные (статические и автоматические) будут доступны только с помощью указателей их типа или типов символов; люди, пишущие C99, решили добавить дополнительные ограничения для выделенного хранилища.
Некоторые компиляторы предлагают средства, с помощью которых код может гарантировать, что доступ с использованием разных типов будет проходить через память (или, по крайней мере, вести себя так, как если бы они это делали), но, к сожалению, я не думаю, что для этого существует какой-либо стандарт. C14 добавила модель памяти для использования с многопотоковой обработкой, которая должна быть способна к достижению требуемой семантики, но я не думаю, что компиляторы должны соблюдать такую семантику в тех случаях, когда они могут сказать, что для внешних потоков нет доступа к чему-либо [ даже если переход через память будет необходим для достижения правильной однопоточной семантики].
Если вы используете gcc и хотите иметь семантику памяти, которая работает как K & R, используйте параметр командной строки «-fno-strict-aliasing». Чтобы сделать код эффективным, необходимо будет существенно использовать «ограничивающий» квалификатор, который был добавлен в C99.Хотя авторы gcc, похоже, больше сосредоточились на правилах псевдонимов на основе типов, чем «ограничить», последнее должно позволить более полезные оптимизации.
Здесь есть тонна UB. Это домашняя проблема? – user3528438
Какое желаемое поведение? Вы не говорите об этом. Вы играете с указателями и типами, вы получаете некоторые экспериментальные результаты, и вы спрашиваете, почему они происходят. Но чего вы ожидали, и чего вы ожидали? –
, если вы ожидаете, что все указатели будут показаны 25, это не может быть правдой, прочитайте о mantissa –