SunCC с 5.12 по 5.14 и "Типы не могут быть объявлены в анонимном объединении"

Мы ловим предупреждение о компиляции под SunCC с 5.12 по 5.14. Другие компиляторы, такие как Clang, GCC, ICC и MSVC, не жалуются. Я не уверен насчет диагностики, потому что раньше не сталкивался с ней.

Код, о котором идет речь, предназначен для BigInteger класс и проблемный союз следует. Класс пытается найти наибольшее машинное слово, которое может содержать сложения с переносами и умножения, которые могут быть выполнены с использованием аппаратного обеспечения, такого как umulx,

       class Dword
       {
         ...
         private:
320        union
321        {
322        #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
323          dword m_whole;
324        #endif
325          struct
326          {
327          #ifdef IS_LITTLE_ENDIAN
328            word low;
329            word high;
330          #else
331            word high;
332            word low;
333          #endif
334          } m_halfs;
335        };
336      };

Вот предупреждение:

[  3%] Building CXX object CMakeFiles/cryptopp-object.dir/integer.cpp.o
/opt/solarisstudio12.3/bin/CC -fPIC -native -m64 -template=no%extdef -o CMakeFiles/cryptopp-object.dir/integer.cpp.o
-c /export/home/jwalton/cryptopp/integer.cpp
CC: Warning: -xchip=native detection failed, falling back to -xchip=generic
"/export/home/jwalton/cryptopp/integer.cpp", line 335: Warning: Types cannot be declared in anonymous union.
1 Warning(s) detected.

Согласно Microsoft в Anonymous Unions:

Простое исключение части имени класса в синтаксисе не делает объединение анонимным объединением. Чтобы объединение считалось анонимным объединением, объявление не должно объявлять объект.

Если я правильно понимаю вещи, у нас есть анонимная структура, потому что никто не может создать экземпляр частного члена struct {...} m_halfs начиная со строки 325. Затем SunCC жалуется, что в анонимном союзе есть член struct {...} m_halfs, Это верно?

Если struct {...} m_halfs в чем проблема, то как мы можем очистить ее портативным способом?

Если это не проблема, то на что жалуется SunCC?


Я должен быть осторожен с тем, как эта проблема проясняется. Производительность является главным приоритетом, и код находится на критическом пути. Также мы поддерживаем GCC 3 и VC++ 6.0 для современных компиляторов; и C++03, C++11, C++14 и C++17.

И последний вопрос: должны ли мы "ничего не делать" и жить с этим на Солярисе?

1 ответ

Решение

N4296 (который является первым проектом стандарта C++ 17) гласит:

Союз формы

      union { member-specification } ; 

называется анонимным союзом; он определяет безымянный объект безымянного типа. Каждое объявление члена в спецификации члена анонимного объединения должно либо определять нестатический элемент данных, либо быть объявлением static_assert. [ Примечание: вложенные типы, анонимные объединения и функции не могут быть объявлены в анонимном объединении. - конец примечания]

Это именно то, что у вас есть здесь - у вас нет имени класса или имени члена, поэтому вы не можете изобретать новый тип структуры для m_halfs, Я предлагаю убрать определение структуры из объединения.

   class Dword
   {
     ...
     private:
        struct word_struct
        {
        #ifdef IS_LITTLE_ENDIAN
            word low;
            word high;
        #else
            word high;
            word low;
        #endif
       };
       union
       {
       #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
           dword m_whole;
       #endif
           word_struct m_halfs;
       };
   };

Это не повлияет на производительность (но учтите, что эта хитрость использования объединений для доступа к различным частям переменной может противоречить строгим правилам алиасинга - это означает, что ваша программа может иметь неопределенное поведение.)

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