2016-09-15 2 views
1

Wir fangen eine Kompilierung Warnung unter SunCC 5.12 bis 5.14. Andere Compiler wie Clang, GCC, ICC und MSVC beschweren sich nicht. Ich bin mir über die Diagnose nicht sicher, weil ich ihr vorher noch nicht begegnet bin.SunCC 5.12 bis 5.14 und "Typen können nicht in anonymer Union deklariert werden"

Der betreffende Code ist für eine BigInteger class und die problematische Union folgt. Die Klasse versucht, das größte Maschinenwort zu finden, das Adds-with-Carries und Multiplies aufnehmen kann, die mit Hardware wie umulx ausgeführt werden können.

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

Hier ist die Warnung:

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

Laut Microsoft bei Anonymous Unions:

einfach Weglassen der Klassenname Teil der Syntax nicht eine Vereinigung eine anonyme Union machen. Damit sich eine Union als anonyme Union qualifiziert, darf die Deklaration kein Objekt deklarieren.

Wenn ich die Dinge richtig verstehe, wir tun eine anonyme Struktur haben, weil niemand das private Mitglied instanziiert kann struct {...} m_halfs ab Zeile 325. Dann wird SunCC die anonyme Vereinigung beschwert hat das Mitglied struct {...} m_halfs. Ist das korrekt?

Wenn struct {...} m_halfs das Problem ist, wie können wir es dann auf tragbare Weise erledigen?

Wenn es nicht das Problem ist, worüber beschwert sich SunCC?


Ich muss vorsichtig sein, wie dieses Problem behoben wurde. Leistung hat oberste Priorität und der Code befindet sich auf dem kritischen Pfad. Außerdem unterstützen wir GCC 3 und VC++ 6.0 gegenüber modernen Compilern. und C++ 03, C++ 11, C++ 14 und C++ 17.

Eine letzte Frage ist, sollten wir "nichts tun" und damit auf Solaris leben?

Antwort

3

N4296 (die die firstdraft des C++ 17-Standard), sagt:

eine Vereinigung von Form

 union { member-specification } ; 

eine anonymous Union genannt wird; Es definiert ein unbenanntes Objekt vom unbenannten Typ. Jedes Mitglied Deklaration im Mitglied-Spezifikation eine anonymen Union wird entweder ein nicht-statisches Datenelement definieren oder eine static_assert Deklaration sein. [Hinweis: geschachtelte Typen, anonyme Verbindungen und Funktionen können nicht innerhalb einer anonymen Union deklariert werden. - Endnote]

das ist genau das, was Sie hier haben - Sie müssen nicht einen Klassennamen oder einen Mitgliedsnamen haben, so dass Sie nicht erlaubt einen neuen Strukturtyp für m_halfs zu erfinden. Ich schlage vor, die Strukturdefinition aus der Union zu entfernen.

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

Dies hat keine Auswirkungen auf der Leistung hat (aber beachten Sie, dass dieser Trick Gewerkschaften der Verwendung verschiedene Teile einer Variable zuzugreifen Foul der strengen Aliasing Regeln fallen können -., Die Ihr Programm bedeuten nicht definiertes Verhalten haben kann)

+0

Vielen Dank. Ich habe bereits ein Zweig-Setup zum Testen von Änderungen hier. * "... aber beachte, dass dieser Trick, Gewerkschaften zu verwenden, um auf verschiedene Teile einer Variablen zuzugreifen ..." * - Ja, das beunruhigt mich. Wir haben dasselbe bei [Initialisierung eines __m128-Typs von einem unsignierten 64-Bit-Int] (http://stackoverflow.com/a/38547909/608639) ausgeführt. Ich wünschte mir wirklich, C++ wäre im Bereich "active union member access" entspannter. Jedes C++ - Programm, das C-Code enthält, könnte aufgrund eines solchen allgemeinen Musters gefährdet sein. – jww

+0

@ M.M: Oops. Sie haben recht, es ist der neueste Entwurf des C++ 17-Standards. Ich habe den Text korrigiert (und einen Link eingefügt). –

+0

@MartinBonner - Für was es wert ist, wurde SunCC 12.3 im November 2012 veröffentlicht. Sein C++ - Compiler unterstützt nicht -std = C++ 03' oder '-std = C++ 11'; Ich glaube, dass C++ 03 eingebrannt ist. Sun Studio 12.4 C++ Compiler war der erste, der C++ 11 zur Verfügung stellte. Oracle hat C++ 14 oder C++ 17 noch nicht unterstützt. Ich vermute (eine reine Vermutung), wird C++ 14 Unterstützung in den nächsten Jahren ankommen. C++ 17 könnte im Jahr 2020 oder so verfügbar sein ... – jww

Verwandte Themen