2016-09-15 3 views
1

Nous recueillons un avertissement de compilation sous SunCC 5.12 à 5.14. D'autres compilateurs, comme Clang, GCC, ICC et MSVC ne se plaignent pas. Je ne suis pas sûr du diagnostic parce que je ne l'ai pas rencontré auparavant.SunCC 5.12 à 5.14 et «Les types ne peuvent pas être déclarés en union anonyme»

Le code en question est pour BigInteger class et l'union problématique suit. La classe tente de trouver le mot machine le plus volumineux pouvant contenir des add-to-carry et des multiplies qui peuvent être effectués à l'aide de matériel tel que 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  }; 

est ici l'avertissement:

[ 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. 

Selon Microsoft à l'adresse Anonymous Unions:

simplement en omettant la partie classe nom de la syntaxe ne fait pas une union, une union anonyme. Pour qu'un syndicat soit qualifié d'union anonyme, la déclaration ne doit pas déclarer un objet.

Si je comprends les choses correctement, nous faire ont une struct anonyme parce que personne ne peut instancier le député struct {...} m_halfs à partir de la ligne 325. Ensuite, SunCC auprès du syndicat anonyme a le membre struct {...} m_halfs. Est-ce exact?

Si struct {...} m_halfs est le problème, alors comment pouvons-nous l'effacer de manière portable?

Si ce n'est pas le problème, alors à quoi se plaint SunCC?


Je dois faire attention à la résolution de ce problème. La performance est une priorité et le code est sur le chemin critique. En outre, nous soutenons GCC 3 et VC++ 6.0 aux compilateurs contemporains; et C++ 03, C++ 11, C++ 14 et C++ 17. Une dernière question est la suivante: devrions-nous "ne rien faire" et vivre avec Solaris?

Répondre

3

N4296 (qui est le firstdraft de la norme 17 C++) dit:

Une union de la forme

 union { member-specification } ; 

est appelé un union anonyme; il définit un objet sans nom de type sans nom. Chaque membre-déclaration dans le membre spécification d'une union anonyme doit soit définir un élément de données non-statique ou une static_assert-déclaration. [note: Les types imbriqués, les unions anonymes et les fonctions ne peuvent pas être déclarées dans une union anonyme. - end note]

C'est exactement ce que vous avez ici - vous ne disposez pas d'un nom de classe ou un nom de membre, vous n'êtes pas autorisé à inventer un nouveau type de struct pour m_halfs. Je suggère de déplacer la définition de struct hors de l'union.

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; 
     }; 
    }; 

Cela aura pas d'impact sur les performances (mais notez que cette astuce d'utiliser les syndicats pour accéder aux différentes parties d'une variable peut tomber sous le coup des règles de crénelage strictes -. Qui signifie que votre programme peut avoir un comportement non défini)

+0

Merci beaucoup. J'ai déjà installé une branche pour tester les modifications ici. * "... mais notez que cette astuce consiste à utiliser les syndicats pour accéder aux différentes parties d'une variable ..." * - ouais, ça m'inquiète. Nous avons rencontré la même chose à [Initialisation d'un type __m128 à partir d'un entier non signé 64 bits] (http://stackoverflow.com/a/38547909/608639). Je souhaitais vraiment que C++ soit plus détendu dans la zone d'accès des membres actifs. N'importe quel programme C++ qui inclut du code C pourrait être en danger parce que c'est un tel modèle commun. – jww

+0

@ M.M: Oups. Vous avez raison, c'est le dernier brouillon de la norme C++ 17. J'ai corrigé le texte (et mis un lien). –

+0

@MartinBonner - Pour sa valeur, SunCC 12.3 a été publié en novembre 2012. Son compilateur C++ ne supporte pas '-std = C++ 03' ou' -std = C++ 11'; Je crois que C++ 03 est cuit dedans. Le compilateur C++ de Sun Studio 12.4 a été le premier à fournir C++ 11. Oracle n'a pas encore fourni le support C++ 14 ou C++ 17. Je devine (un son purement une conjecture), le support C++ 14 arrivera dans les deux prochaines années. C++ 17 pourrait être disponible en 2020 ou alors ... – jww