SunCC 5.12 到 5.14 和“不能在匿名联合中声明类型”

Posted

技术标签:

【中文标题】SunCC 5.12 到 5.14 和“不能在匿名联合中声明类型”【英文标题】:SunCC 5.12 through 5.14 and "Types cannot be declared in anonymous union" 【发布时间】:2016-09-15 07:41:30 【问题描述】:

我们在 SunCC 5.12 到 5.14 下发现了一个编译警告。其他编译器,如 Clang、GCC、ICC 和 MSVC 不会抱怨。我不确定诊断,因为我以前没有遇到过。

有问题的代码是针对BigInteger class 的,有问题的联合如下。该类试图找到最大的机器字,可以容纳可以使用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.

据微软Anonymous Unions:

仅仅省略语法的类名部分不会使联合成为匿名联合。要使联合符合匿名联合的条件,声明中不得声明对象。

如果我理解正确,我们确实有一个匿名结构,因为没有人可以从第 325 行开始实例化私有成员 struct ... m_halfs。然后,SunCC 抱怨匿名联合有成员 @ 987654328@。对吗?

如果struct ... m_halfs 是问题所在,那么我们如何以便携的方式清除它?

如果不是问题,那么 SunCC 在抱怨什么?


我必须小心这个问题是如何解决的。性能是重中之重,代码在关键路径上。此外,我们支持现代编译器的 GCC 3 和 VC++ 6.0;和 C++03、C++11、C++14 和 C++17。

最后一个问题是,我们是否应该“什么都不做”并在 Solaris 上接受它?

【问题讨论】:

【参考方案1】:

N4296(这是 C++ 17 标准的初稿)说:

形式的联合

      union  member-specification  ; 

被称为匿名联合;它定义了一个未命名类型的未命名对象。 每个成员声明 在匿名联合的成员规范中,要么定义一个非静态数据成员,要么是一个 静态断言声明。 [ 注意:嵌套类型、匿名联合和函数不能在其中声明 一个匿名的工会。 — 尾注]

这正是你在这里所拥有的——你没有类名或成员名,所以你不能为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;
       ;
   ;

这不会影响性能(但请注意,使用联合访问变量不同部分的技巧可能会违反严格的别名规则 - 这意味着您的程序可能具有未定义的行为。)

【讨论】:

非常感谢。我已经有了一个分支设置来测试这里的任何更改。 "...但请注意,使用联合访问变量不同部分的技巧..." - 是的,这让我很担心。我们在Initializing an __m128 type from a 64-bit unsigned int 遇到了同样的问题。我真的希望 C++ 在“活跃的工会成员访问”领域更加轻松。任何包含 C 代码的 C++ 程序都可能存在风险,因为它是一种常见的模式。 @MM:哎呀。你说的很对,它是 C++17 标准的最新草案。我已经修复了文本(并添加了链接)。 @MartinBonner - 值得一提的是,SunCC 12.3 于 2012 年 11 月发布。它的 C++ 编译器不支持-std=c++03-std=c++11;我相信 C++03 已经融入其中。Sun Studio 12.4 C++ 编译器是第一个提供 C++11 的。 Oracle 尚未提供 C++14 或 C++17 支持。我在猜测(纯粹是猜测),C++14 支持将在未来几年内到来。 C++17 可能会在 2020 年左右推出...... N4296 是第一个 C++17 草案...我知道的最新版本是 N4606 嗯。我从isocpp.org/std/the-standard 获得了该文档,该文档在“从何处获取当前标准 (C++14)”中进行了描述。

以上是关于SunCC 5.12 到 5.14 和“不能在匿名联合中声明类型”的主要内容,如果未能解决你的问题,请参考以下文章

机器视觉 HDevelop语言基础-变量和表达式

5.12下午

(5.14)mysql高可用系列——级联复制

5.12流片delay复盘

PyQt QtWebengineWidgets 与 PyQt 5.12

从 Perl 5.14 升级到 5.28 后,我的 Perl 找不到 local::lib