Мы ловим предупреждение о компиляции под 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 в Анонимные Союзы:
Простое исключение части имени класса в синтаксисе не делает объединение анонимным объединением. Чтобы объединение считалось анонимным объединением, объявление не должно объявлять объект.
Если я правильно понимаю вещи, мы делать иметь анонимную структуру, потому что никто не может создать экземпляр частного члена 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.
И последний вопрос: должны ли мы «ничего не делать» и жить с этим на Солярисе?
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;
};
};
Это не повлияет на производительность (но учтите, что эта хитрость использования объединений для доступа к различным частям переменной может противоречить строгим правилам алиасинга — это означает, что ваша программа может иметь неопределенное поведение.)
Других решений пока нет …