Определение массива без размера или нулевого размера

Я наткнулся на приведенный ниже код, который меня сбил с толку:

union
{
    struct
    {
        uint32_t Id;
        uint8_t a_data[];
    }vendor;
    uint8_t avp[0];
}data;

Это нормально компилируется с g ++ 7.2.1, но я не могу понять почему. Как нет необходимости указывать размер при определении a_data? Как у avp может быть нулевой размер?

a_data[] является стандартом C99 и не всегда поддерживается компиляторами C++. Использование uint8_t avp[0]; в качестве гибкого члена является исключительно расширением GCC для той же цели и не должно использоваться вообще. Это восходит к 1969 году. Некоторые другие компиляторы могут рассматривать его как массив нулевого размера, и любой доступ будет вне границ.
Swift - Friday Pie 13.09.2018 08:22
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это гибкий элемент массива и технически не является частью C++ (это функция только для C).

Некоторые компиляторы (особенно GCC) с радостью добавляют функции из C как расширения в C++. Таким образом, он не переносится, и вам следует по возможности избегать такого кода.

Это потому, что GCC - это компилятор C, и эта функция ISO C99 ... G ++ - это компилятор C++, который сохраняет функции GCC. Интересно, как они относятся к строгому сглаживанию, когда имеют дело с этим. По крайней мере, три большие платформы используют это расширение, WIndows API написан с его использованием, и я поймал, что мои коллеги переносят это в своем коде с Windows на Linux. Потому что они думают, что это стандарт. Но Windows API также написан с функциями, имеющими несколько точек входа.

Swift - Friday Pie 13.09.2018 08:11

Это ужасный способ инициализировать объект структуры, но его очень приятно знать!

Frederik.L 13.09.2018 08:13

@ Swift-FridayPie Я использую термин «GCC» как сокращение от «GNU Compiler Collection» (так он официально используется). И несмотря ни на что, gcc и g++программы могут компилировать исходные файлы как на C, так и на C++. Разница между интерфейсными программами gcc и g++ заключается в некотором флаге, который они передают фактическому компилятору и компоновщику.

Some programmer dude 13.09.2018 08:13

@ Frederik.L было время, когда в libjpeg была уязвимость, основанная на использовании этой функции. Так легко описать формат файла, в котором фиксированные заголовки располагались в начале. Проблема в том, как после этого управлять доступом к памяти.

Swift - Friday Pie 13.09.2018 08:17

Другие вопросы по теме