-
- Чего ты привязался к memcpy. Я рассказал выше как получается баг. Вместо memcpy может быть любое обращение по указателю/ссылке. К слову и gcc и clang даже варнинг имеют специальный:
-Waddress-of-packed-member. Его невозможно выполнить в любом коде.
А ты хочешь сказать, мол memcpy на 32-битной машине должен
копировать по байтику вместо 4-х за раз, а на 64-битной по байтику
вместо 8, а на машинах где есть векторные инструкции... вообще
страшно. И да, оптимизатор fk0(728 знак., 26.07.2020 15:24)
- Я привязался к memcpy ровно потому, что ее параметры прямо декларируются как void*. void* означает, что указатель может быть любым. И компилятор обязан этот факт учитывать. Тяготы и лишения
компиляторописателей меня интересуют постольку-поскольку. - LightElf(26.07.2020 15:35)
- И он работает с любым типом корректно. Пока ему голову не
заморочили взятием указателя на выровненный тип в упакованной
структуре. В каком-то смысле, это недоработка компилятора, но
стандарт не нарушается. - Nikolay_Po(26.07.2020 15:39)
- Мы говорим о нестандартном (но весьма распространенном) расширении.
Причем тут ссылки стандарт? - LightElf(26.07.2020 15:42)
- ОК. С точки зрения работы расширения проблема налицо. Но fk0 принялся ругать говнокод и защищать компилятор. За что ему большое спасибо! Всё подробно разжевал, ссылки привёл. Тема была - супер!!! - Nikolay_Po(26.07.2020 15:47)
- Тогда на что ссылаться? По стандарту всё ок. А по мнению LightElf
не ок? Нужен какой-то формальный документ, который описывает
поведение компилятора. - fk0(26.07.2020 15:44)
- На документацию конкретного компилятора - LightElf(26.07.2020 15:48)
- Где в документации описывается что должно происходить в случаях: fk0(232 знак., 26.07.2020 15:59)
- А знаешь почему не описывается? Сям (компилеру и стандарту) просто
чхать, какая там структура. Осознай это. Упакованная, не
упакованная - именно сишечке по барабану. Осознай: требования по
default data alignment (вообще по типам, не только выравнивание, но
и размер) оно существует только для конкретной CPU платформы, не у
компилятора. И padding (выравнивание) структур делает не компилятор
следующий стандарту C, а бэкенд, именно он отвечает за платформу,
ее выравнивание, RxTx(223 знак., 26.07.2020 17:22)
- В пятый раз повторяю, компилятор знает и используют такое понятие
как alignof/alignas для любого типа данных, у gcc есть расширение
-- атрибут __attribute__((aligned(N))), по аналогии с typeof() есть
__alignof __(type) (в голом C, без C++). В голом C на него можно
нарваться через generics, через sizeof() тоже можно если
постараться. Именно что платформо-независимый генератор кода уже
всем этим оперирует. Отнюдь не бэкенд. - fk0(26.07.2020 17:23)
- Ты слишком поспешно тут сделал выводы насчет "уже всем этим
оперирует". Предупрежу что абсолютно точно в коде работы с
атрибутами я не разбирался (хотя по аналогии с кодом/проблемой ТС
ничто не мешает, просто лень/занятость). Все что ты перечислил -
"тонкие нити" информации, которые 11й компилер вытягивает из
констант существующих в кодогенерящем/платформозависимом BackEnd'е. RxTx(822 знак., 26.07.2020 18:12)
- Смешались в кучу люди, кони... Причём здесь бэкенд вообще и зачем знать как он устроен, если в документации, в справочнике для программиста явно сказано как оперировать этими атрибутами? Оно программисту средствами языка доступно. На самом верхнем уровне. Следовательно компилятор такими атрибутами тоже оперирует. - fk0(26.07.2020 22:21)
- Ты слишком поспешно тут сделал выводы насчет "уже всем этим
оперирует". Предупрежу что абсолютно точно в коде работы с
атрибутами я не разбирался (хотя по аналогии с кодом/проблемой ТС
ничто не мешает, просто лень/занятость). Все что ты перечислил -
"тонкие нити" информации, которые 11й компилер вытягивает из
констант существующих в кодогенерящем/платформозависимом BackEnd'е. RxTx(822 знак., 26.07.2020 18:12)
- В пятый раз повторяю, компилятор знает и используют такое понятие
как alignof/alignas для любого типа данных, у gcc есть расширение
-- атрибут __attribute__((aligned(N))), по аналогии с typeof() есть
__alignof __(type) (в голом C, без C++). В голом C на него можно
нарваться через generics, через sizeof() тоже можно если
постараться. Именно что платформо-независимый генератор кода уже
всем этим оперирует. Отнюдь не бэкенд. - fk0(26.07.2020 17:23)
- Логично, что implementation defined behaviour должен быть описан в
документации конкретного implementation. Разве не так? - LightElf(26.07.2020 17:21)
- Логично! И где, ткните меня носом! - fk0(26.07.2020 17:24)
- Я ж говорю - баг! "A conforming implementation of ISO C is required
to document its choice of behavior in each of the areas that are
designated “implementation defined”." - LightElf(26.07.2020 18:02)
- Подразумевается areas из стандарта C, а не вообще всё реализованное
компилятором. - fk0(26.07.2020 18:07)
- Большинство приличных компиляторов документируют свои расширения и
их особенности. Вот что пишет IAR: LightElf(524 знак., 27.07.2020 00:03)
- А что будет при обмене "int *" и "packed int*"
указателями/ссылками? Они не совместимы вообще? Это, то что я имею
ввиду, когда говорю, мол сделать можно, но программисту
программировать будет невозможно. - fk0(27.07.2020 00:05)
- Так уже обсуждали. Конечно, если передавать __packed int* функциям типа scanf, на некоторых архитектурах могут быть сюрпризы. Имхо, корень зла тут не в атрибуте __packed, а в функции с ... в списке параметров. - йцyкeн(27.07.2020 13:11, ссылка)
- Будет диагностика "Warning[Pa039]: use of address of unaligned
structure member". Код будет нерабочий. Что, в общем-то, и
ожидается. - LightElf(27.07.2020 00:31)
- Код будет где-то рабочий а где-то нет. На AVR рабочий, на Cortex-M3
и ESP32 рабочий а на M0 и ESP8266 получим hard fault. И варнинг
тогда уж надо выдавать в зависимости от архитектуры процессора. - 3m(27.07.2020 07:16)
- Неа. IAR этот варнинг и на CM4 выдает. Этот код непортабелен и уже потому должен вызывать варнинг. Логика должна быть такая: "ты тут чего-то странное на$%евертил, я это как-то скомпилю, но не обижайся если что". . Другое дело, что "у меня все работает", потому что выровненность полей структуры достигается другими методами (о которых компилятор не знает). - LightElf(27.07.2020 14:48)
- Код будет где-то рабочий а где-то нет. На AVR рабочий, на Cortex-M3
и ESP32 рабочий а на M0 и ESP8266 получим hard fault. И варнинг
тогда уж надо выдавать в зависимости от архитектуры процессора. - 3m(27.07.2020 07:16)
- А что будет при обмене "int *" и "packed int*"
указателями/ссылками? Они не совместимы вообще? Это, то что я имею
ввиду, когда говорю, мол сделать можно, но программисту
программировать будет невозможно. - fk0(27.07.2020 00:05)
- Большинство приличных компиляторов документируют свои расширения и
их особенности. Вот что пишет IAR: LightElf(524 знак., 27.07.2020 00:03)
- Подразумевается areas из стандарта C, а не вообще всё реализованное
компилятором. - fk0(26.07.2020 18:07)
- Я ж говорю - баг! "A conforming implementation of ISO C is required
to document its choice of behavior in each of the areas that are
designated “implementation defined”." - LightElf(26.07.2020 18:02)
- Логично! И где, ткните меня носом! - fk0(26.07.2020 17:24)
- А знаешь почему не описывается? Сям (компилеру и стандарту) просто
чхать, какая там структура. Осознай это. Упакованная, не
упакованная - именно сишечке по барабану. Осознай: требования по
default data alignment (вообще по типам, не только выравнивание, но
и размер) оно существует только для конкретной CPU платформы, не у
компилятора. И padding (выравнивание) структур делает не компилятор
следующий стандарту C, а бэкенд, именно он отвечает за платформу,
ее выравнивание, RxTx(223 знак., 26.07.2020 17:22)
- Где в документации описывается что должно происходить в случаях: fk0(232 знак., 26.07.2020 15:59)
- На документацию конкретного компилятора - LightElf(26.07.2020 15:48)
- Мы говорим о нестандартном (но весьма распространенном) расширении.
Причем тут ссылки стандарт? - LightElf(26.07.2020 15:42)
- Я выше сказал, что проблема возникает не в memcpy, а в выражении
&IH.conag. Что там после -- уже не важно. Результат данного
выражения не валиден. Он содержит корректное числовое значение, но
некорректный тип, из-за чего оптимизатор принимает не верное
решение. - fk0(26.07.2020 15:39)
- Блин. Писатели GCC сами добавили в свой компилятор поддержку упакованых структур. И не
осилили ее корректно реализовать (в отличие от других
компиляторов). А ты пытаешься убедить всех, что это не баг, а фича. - LightElf(26.07.2020 15:46)
- Вот именно в этом я и пытаюсь убедить -- что сами упакованные
структуры нихрена не продуманная "фича", страдающая множественными
дефектами и не совместимостью со стандартным языком C/C++. Поэтому
её нет в стандарте. Потому, что куда не ткнись, любое нетривиальное
использование (кроме непосредственного обращения к членам как к
значениям) -- неопределённое поведение. А как код-то писать? Шаг
влево-вправо -- "баги". - fk0(26.07.2020 16:02)
- А я тебе и говорю, что неопределенное поведение упакованных
структур - это изначально косяк стандартизаторов языка. Эта фича
есть во всех вменяемых компиляторах с лохматых времен. Наверно она
нужна зачем-то. И все ее как-то реализуют. Но пуристы в комитете
предпочитают прятать голову в песок и изобретают всякую никому не
нужную хрень, вместо введения упакованных структур в стандарт. С
описанием их конкретного поведения в разных случаях. Например,
можно указать что адрес члена LightElf(139 знак., 26.07.2020 18:00)
- В основе языка C лежит ЯВУ (B)CPL к которому добавлены системные возможности. Структуры (record, записи) в ЯВУ могут быть представлены неупорядоченными множествами. Для несистемного языка этого вполне достаточно. В С структуры появились не сразу, первые версии были без структур и Ричи сразу планировал прямое соответствие описания структур фактическому бинарному (битовому) расположению в памяти. К тому же первые версии C создавались для CISC машин, поэтому в оригинале RxTx(1382 знак., 29.07.2020 14:43)
- Косяк стандартизаторов в том, что этой недофичи попросту нет в
стандарте? Оригинально. Её и не хотят принимать, потому, что очень
много спорных моментов возникает. Значит компилятор должен уметь
генерировать код умеющийся обращаться к невыравненным данным вообще
(сейчас такой обязанности у компилятора нет). Значит объявление
такой структуры должно автоматически вводит множество типов
унаследованных от базовых (типа int), но со своим выравниванием.
Значит эти типы должны fk0(375 знак., 26.07.2020 18:06)
- Все эти спорные моменты уже давно решены и реализованы. Так или
иначе. Почему бы просто не стандартизовать ежу существующее
поведение? - LightElf(26.07.2020 18:10)
- А где задокументировано, как они решены и реализованы? Если нигде,
то что тогда стандартизировать? Я что-то не уверен, что всё прямо
так решено: в начале топика я давал ссылку -- смотри, оно
упакованный тип от неупакованного в упор не отличает. Легко это
превратить в баг. И присваивание указателей, значит, проканает без
ошибок. fk0(248 знак., 26.07.2020 22:19, ссылка, ссылка)
- ну смотри, проблема такая (паддинг, упакованные типы) существует?
существует. другие проблемы связанные с физической реализацией
работы с конкретными типами существуют? существуют. (переполнения
там, арифметика с насыщением). так почему бы хоть какое-то общее
множество не внести в стандарт? слишком уж далеко виртуальная
абстрактная машина стала абстрагироваться от существующей
физической реализации АЛУ в процессорах. - Mahagam(29.07.2020 15:28)
- Потому, что весь топик об этом. Чтоб внести в стандарт упакованные
структуры -- нужно вообще ввести новые типы данных не совместимые с
существующими (с чего баг начался). - fk0(29.07.2020 17:41)
- а может хватило бы модификатора? по типу volatile. который не меняет тип, но меняет работу с ним. Mahagam(130 знак., 30.07.2020 01:15)
- Потому, что весь топик об этом. Чтоб внести в стандарт упакованные
структуры -- нужно вообще ввести новые типы данных не совместимые с
существующими (с чего баг начался). - fk0(29.07.2020 17:41)
- ну смотри, проблема такая (паддинг, упакованные типы) существует?
существует. другие проблемы связанные с физической реализацией
работы с конкретными типами существуют? существуют. (переполнения
там, арифметика с насыщением). так почему бы хоть какое-то общее
множество не внести в стандарт? слишком уж далеко виртуальная
абстрактная машина стала абстрагироваться от существующей
физической реализации АЛУ в процессорах. - Mahagam(29.07.2020 15:28)
- А где задокументировано, как они решены и реализованы? Если нигде,
то что тогда стандартизировать? Я что-то не уверен, что всё прямо
так решено: в начале топика я давал ссылку -- смотри, оно
упакованный тип от неупакованного в упор не отличает. Легко это
превратить в баг. И присваивание указателей, значит, проканает без
ошибок. fk0(248 знак., 26.07.2020 22:19, ссылка, ссылка)
- Все эти спорные моменты уже давно решены и реализованы. Так или
иначе. Почему бы просто не стандартизовать ежу существующее
поведение? - LightElf(26.07.2020 18:10)
- А я тебе и говорю, что неопределенное поведение упакованных
структур - это изначально косяк стандартизаторов языка. Эта фича
есть во всех вменяемых компиляторах с лохматых времен. Наверно она
нужна зачем-то. И все ее как-то реализуют. Но пуристы в комитете
предпочитают прятать голову в песок и изобретают всякую никому не
нужную хрень, вместо введения упакованных структур в стандарт. С
описанием их конкретного поведения в разных случаях. Например,
можно указать что адрес члена LightElf(139 знак., 26.07.2020 18:00)
- Вот именно в этом я и пытаюсь убедить -- что сами упакованные
структуры нихрена не продуманная "фича", страдающая множественными
дефектами и не совместимостью со стандартным языком C/C++. Поэтому
её нет в стандарте. Потому, что куда не ткнись, любое нетривиальное
использование (кроме непосредственного обращения к членам как к
значениям) -- неопределённое поведение. А как код-то писать? Шаг
влево-вправо -- "баги". - fk0(26.07.2020 16:02)
- Блин. Писатели GCC сами добавили в свой компилятор поддержку упакованых структур. И не
осилили ее корректно реализовать (в отличие от других
компиляторов). А ты пытаешься убедить всех, что это не баг, а фича. - LightElf(26.07.2020 15:46)
- И он работает с любым типом корректно. Пока ему голову не
заморочили взятием указателя на выровненный тип в упакованной
структуре. В каком-то смысле, это недоработка компилятора, но
стандарт не нарушается. - Nikolay_Po(26.07.2020 15:39)
- Я привязался к memcpy ровно потому, что ее параметры прямо декларируются как void*. void* означает, что указатель может быть любым. И компилятор обязан этот факт учитывать. Тяготы и лишения
компиляторописателей меня интересуют постольку-поскольку. - LightElf(26.07.2020 15:35)
- Чего ты привязался к memcpy. Я рассказал выше как получается баг. Вместо memcpy может быть любое обращение по указателю/ссылке. К слову и gcc и clang даже варнинг имеют специальный:
-Waddress-of-packed-member. Его невозможно выполнить в любом коде.
А ты хочешь сказать, мол memcpy на 32-битной машине должен
копировать по байтику вместо 4-х за раз, а на 64-битной по байтику
вместо 8, а на машинах где есть векторные инструкции... вообще
страшно. И да, оптимизатор fk0(728 знак., 26.07.2020 15:24)