Что не так с этим использованием offsetof?

Я компилирую некоторый код C++ в MinGW GCC 4.4.0 и получаю предупреждения со следующей формой...

warning: invalid access to non-static data member ''  of NULL object
warning: (perhaps the 'offsetof' macro was used incorrectly)

Эта проблема кажется знакомой - что-то, что я попытался разрешить прежде и перестал работать, я думаю, но только что. Сборки кода, прекрасные в Visual C++, но я недавно не создал этот конкретный код ни в каком другом компиляторе.

Проблемный код является следующим шаблоном...

template
class c_Align_Of
{
  private:
    struct c_Test
    {
      char m_Char;
      T    m_Test;
    };
  public:
    enum { e_Align = offsetof (c_Test, m_Test) };
};

Очевидно, я могу, вероятно, использовать некоторую условную компиляцию для использования определенных для компилятора функций для этого, и я полагаю, что C++ 0x (в конце концов) сократит ее. Но в любом случае, я не вижу ничто плохого с этим использованием offsetof.

Очень педантично это возможно это потому что T типами параметра иногда является не-POD, таким образом, классы GCC c_Test как не-POD и жалуется (и жалуется и жалуется - я получаю почти 800 строк этих предупреждений).

Это непослушно строгой формулировкой стандарта, так как типы не-POD могут повредиться offsetof. Однако этот вид не-POD не должен быть проблемой на практике - c_Test не будет иметь виртуальной таблицы, и никакой обман во время выполнения не необходим для нахождения смещения m_Test.

Кроме того, даже если c_Test имел виртуальную таблицу, GCC реализует offsetof макрос с помощью внутреннего, которое всегда оценивается во время компиляции на основе статического расположения того конкретного типа. При обеспечении инструмента, затем жалующегося (извините, предупреждая), каждый раз, когда это использовало просто, кажется глупым.

Кроме того, я не единственный человек здесь, который делает такого рода вещь...

Ответьте на legit-uses-of-offsetof вопрос

Я действительно не забываю иметь проблему с offsetof для этого вида причины, но я не думаю, что проблемой был этот шаблон.

Какие-либо идеи?

20
задан Community 23 May 2017 в 12:10
поделиться

1 ответ

Oops...

Проблема в том, что структура c_Test не является POD из-за того, что тип T не является POD. Вот цитата из руководства GCC...

-Wno-invalid-offsetof (только C++ и Objective-C++)

Подавление предупреждений от применения макроса макроса 'offsetof' к типу, не являющемуся POD.

Согласно стандарту ISO C++ 1998 года стандарту ISO C++ 1998 года, применение макроса 'offsetof' к не-POD-типу является неопределенным. В существующих реализациях C++, однако, 'offsetof' обычно дает значимые результаты даже при применении к определенным типам без POD. (Например простой 'struct', который не является POD типом только в силу того, что у него есть конструктора.) Этот флаг предназначен для пользователей которые знают, что они пишут непортируемый код и которые сознательно решили проигнорировать предупреждение об этом.

Ограничения на 'offsetof' могут быть ослаблены в будущей версии стандарта C++ стандарта.

Моя проблема в том, что почти все мои T-типы имеют конструкторы, и поэтому классифицируются как не-POD. Ранее я проигнорировал этот момент как несущественный - и, конечно, он должен быть несущественным для offsetof в принципе. Проблема в том, что стандарт C++ использует одну классификацию POD vs. non-POD, хотя существует несколько различных способов быть не-POD, и компилятор правильно делает, что по умолчанию предупреждает о нестандартно-совместимом использовании.

Моим решением на данный момент будет приведенная выше опция для подавления предупреждения - теперь мне просто нужно понять, как сказать cmake использовать ее.

34
ответ дан 30 November 2019 в 00:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: