C Есть какой-нибудь способ программно обнаружить POD-структуру?

#c

#c

Вопрос:

У меня есть структура данных, в которой хранятся POD-структуры (каждый экземпляр хранит только один тип, поскольку это в основном массив определенной POD-структуры). Иногда другой разработчик изменяет одну из этих структур, добавляя или модифицируя тип данных. Если добавляется элемент, отличный от POD, например, std::string, структура данных разрушается во время выполнения, поскольку изменяется модель памяти. Есть ли какой-нибудь способ определить, совместим ли класс или структура с POD, используя определения компилятора или вызов во время выполнения (чтобы избежать этой проблемы с сопровождением)? Я использую g (GCC) 4.2.4.

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

1. Обычным подходом к решению этой проблемы является проверка кода.

2. @unapersson: При проверке кода в этом случае часто не удается обнаружить проблему, особенно в больших кодовых базах. Поддержка компилятора — лучший подход.

3. @John Нет. Обзоры кода — лучший способ обнаружить почти все семантические (а не синтаксические) проблемы с кодом.

4. @unapersson: В данном случае я не могу согласиться. Во всех случаях, когда компилятор может вызвать ошибку, он будет делать это всегда , в то время как проверки кода могут пропускать некоторые случаи. Кто-то может использовать тип X в контейнере, и этот тип может содержать другой тип Y , который, в свою очередь, содержит Z … которая может быть изменена на не-pod. Поскольку тип Z никогда не используется непосредственно в контейнере, источник проблемы и сама проблема разделены, и во многих случаях она не будет обнаружена. Независимо от того, насколько далеко продвинуто определение Z , компилятор может обнаружить это намного раньше, чем любая проверка.

5. @unapersson: Мое утверждение основано на опыте. Я участвовал во многих проектах с несколькими MLOC объектами, которые могли бы сломаться, если бы их изменили на не-POD, и при проверке кода иногда не удавалось обнаружить дефект. Когда мы разработали инструменты времени компиляции, которые прерывали компиляцию при изменении этих параметров, частота обнаружения дефектов немедленно достигла 100%. Как может проверка кода когда-либо быть лучше этого? Не поймите меня неправильно, обзоры кода хороши по многим причинам — но они не являются конечным результатом.

Ответ №1:

Во время выполнения, вероятно, нет, но во время компиляции вы можете использовать is_pod trait либо из стандартной библиотеки C 0x, либо Boost.Признаки типов.

 static_assert(std::is_pod<YourStruct>::value);
  

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

1. В C 03 это только половина решения. Вам придется вручную специализировать шаблон для ваших собственных типов, что вернет вас к исходной точке. Кто-то где-то меняет тип, но is_pod<T>::value все равно выдает true, поэтому более поздний вариант static_assert благополучно проходит. Это лучше, чем ничего, но вы должны быть осторожны, чтобы это не привело к ложному чувству безопасности.

2. @DennisZickeoose: Зависит от компилятора. MSVC (по крайней мере, > = 2005, возможно, старше), GCC > = 4.3 (Я думаю) и некоторые другие имеют встроенные функции, которые is_pod используют. Итак, если вы используете древний или иным образом неспособный компилятор, тогда да, это может быть не очень хорошим решением.

3. И поскольку OP использует GCC4.2, это довольно важное различие.

4. @DennisZickeoose: Ах, точно. Что ж, есть простое решение этой проблемы, не используйте древние и неподдерживаемые компиляторы. 😉 Я бы все же сказал, что is_pod — лучший способ, даже если для этого требуется обновление компилятора.

5. Это хорошая информация — спасибо за ответ. К сожалению, на данный момент я не могу переключать компиляторы — поверьте мне, я бы хотел, чтобы я мог.

Ответ №2:

Вероятно, вы можете использовать библиотеку boost type_traits и, в частности, boost::is_pod<T>::value в статическом assert .

Ответ №3:

Если у вас нет boost или C 0x, то, возможно, вы можете использовать какой-то факт, подобный тому, что C не позволяет использовать не-POD в качестве члена union.

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

1. он написан на несовершенном c : D