【问题标题】:C++ packing a typedef enumC++ 打包一个 typedef 枚举
【发布时间】:2011-02-17 00:24:37
【问题描述】:
typedef enum BeNeLux
{
   BELGIUM,
   NETHERLANDS,
   LUXEMBURG
} _ASSOCIATIONS_ BeNeLux;

当我尝试使用 C++ 编译器编译它时,我遇到了错误,但它似乎可以在 C 编译器中正常工作。所以这就是问题所在。是否可以在 C++ 中打包枚举,或者有人可以看到我为什么会收到错误消息?

错误是:

“BeNeLux 声明后缺少分号”。

我知道,在检查和重新检查之后,那里肯定有一个分号,并且在其余代码所需的任何地方。

附录:

_PACKAGE_ 只是一个例子。我正在重命名它。

_ASSOCIATIONS_ 不是比荷卢经济联盟的一种:

#define _ASSOCIATIONS_ __attribute__((packed))

对代码进行了 iffed,但只是为了确保它是 GNU C/C++。

#if defined (__GNUC__) 
#define _ASSOCIATIONS_ __attribute__((packed))
#else
#define _ASSOCIATIONS_

这会导致问题吗?我认为 (GNUC) 适用于 C 和 C++

附录 2:

我什至尝试过

#ifdef __cplusplus
extern "C" {
#endif

    typedef enum BeNeLux
    {
       BELGIUM,
       NETHERLANDS,
       LUXEMBURG
    } _ASSOCIATIONS_ BeNeLux;

#ifdef __cplusplus
}
#endif

没有快乐。有人吗?

注意:-fshort-enums 是不可能的;寻找程序化解决方案。

【问题讨论】:

  • 这是一个非标准功能。你用的是什么 C 编译器?
  • 使用 gcc 3.3.5 或更低版本(必须使用这个旧版本)
  • 打包一个枚举是什么意思?使底层类型尽可能小?
  • _PACK__PACKAGE_ 作为用户定义的宏名称都是非法的。以下划线开头的名称基本上是为编译器的内部标识符和标准库实现保留的。 (规则更复杂,但不要使用前导下划线。)
  • @UncleBens:前导下划线在这里不是问题,因为我可以用 C 编译器很好地编译。 @大卫:是的。这是用于嵌入式编程

标签: c++ c enums compilation packing


【解决方案1】:

更新:

对于 C++11 及更高版本,您可以指定 enums 的基础类型。例如:

enum BeNeLux : uint8_t {
   BELGIUM,
   NETHERLANDS,
   LUXEMBURG
};

但这仅适用于代码仅为 C++ 的情况。如果代码需要同时兼容 C 和 C++,我相信我原来的答案仍然适用。


我认为这里没有什么东西可以完全满足您的要求。我假设您正在尝试创建一个类型,该类型是枚举范围的最小类型。

如果你需要这种类型的控制,我会推荐这样的东西:

typedef unsigned char BeNeLux;
static const BeNeLux BELGIUM = 0;
static const BeNeLux NETHERLANDS = 1;
static const BeNeLux LUXEMBURG = 2;

不那么漂亮,并且可能不那么安全。但有你想要的效果。 sizeof(BeNeLux) == 1 并且您对该范围内的所有值都有一个命名常量。一个好的编译器甚至不会为 static const 整数值分配一个变量,只要你从不尝试使用它的地址。

【讨论】:

    【解决方案2】:
    #if defined (__GNUC__)
    #  if defined (__cplusplus)
    #     define _ASSOCIATIONS_(X) __attribute__((packed))
    #  else
    #     define _ASSOCIATIONS_(X) __attribute__((packed)) X
    #  endif
    #else
    #  if defined (__cplusplus)
    #     define _ASSOCIATIONS_(X)
    #  else
    #     define _ASSOCIATIONS_(X) X
    #  endif
    #endif
    
    typdef enum BeNeLux {
      BELGIUM,
      NETHERLANDS,
      LUXEMBURG
    } _ASSOCIATIONS_ (BeNeLux);
    

    这似乎编译在我的g++ (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)

    【讨论】:

    【解决方案3】:

    这里没有真正的突破。我只是重新排序的东西希望你的 编译器会更喜欢它。我没有你的 gcc 或 g++ 版本,所以我无法用它们进行测试。我确实通过版本 3.4.5 gcc 和 g++(mingw 特殊)运行它,当像您的代码一样订购时,它们都警告'packed' attribute ignored,但没有抱怨我的。

    #ifdef __GNUC__
    #define attribute(x) __attribute__((x));
    #else
    #define attribute(x)
    #endif
    
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    enum BeNeLux
    {
        BELGIUM,
        NETHERLANDS,
        LUXEMBURG
    } attribute(packed);
    // I declared attribute to look like a f() so that it would not look like I was
    // declaring a variable here.
    
    #ifndef __cplusplus
    typedef enum BeNeLux BeNeLux; // the typedef is separated into a separate stmt
    #else
    }
    #endif
    

    【讨论】:

      【解决方案4】:

      在 C++ 中,您不需要 typedef。只需从enum BeNeLux 开始。也有可能(我永远不记得)声明具有相同标识符的类型和变量在其中一种语言中可能是不合法的。

      【讨论】:

      • 附录清楚地表明这不是他想要的。在两种语言中同时声明类型和标识符是不可能的。
      • 我的意思是,同时声明typedef 和标识符是不可能的。
      【解决方案5】:
      enum BeNeLux
      {
         BELGIUM,
         NETHERLANDS,
         LUXEMBURG
      };
      

      这是 C++ 代码所期望的。

      【讨论】:

      • 不,它没有。如果他只是用这个,那他就完了。
      • 没有。问题是“typedef enum”和属性打包。我知道 enum BeNeLux 会起作用,但这不是我需要的。
      【解决方案6】:

      我想您正在使用 GCC 和 G++。对我来说,代码可以很好地编译。当在任何一个特定的编译器上启用 C++ 时,看到这样的功能消失,这将是相当令人惊讶的。

      确保您的 #define 不是针对 C++ 代码的 #if,例如#ifndef __cplusplus.

      尝试g++ -E 查看预处理器输出并验证#define 是否出现。

      此外,即使对于预处理器宏,以下划线和大写字母或两个下划线开头的名称也保留给编译器和库。如果您必须有一个宏,PACKED 可能是它的最佳名称。

      【讨论】:

      • 在没有#ifs的情况下直接添加了该代码,但仍然无法正常工作。
      • @Sagar:同时尝试 gcc -vg++ -v 以确保您获得的版本相同。
      • 根据手册gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_5.html#SEC105,即使在 GCC 2.95 中也应该可以工作。
      【解决方案7】:
      #if defined (__GNUC__)
      
      #  if defined (__cplusplus)
      #     define ENUM enum
      #  else
      #     define ENUM typedef enum
      #  endif
      
      #  if defined (__cplusplus)
      #     define _ASSOCIATIONS_(X) __attribute__((packed))
      #  else
      #     define _ASSOCIATIONS_(X) __attribute__((packed)) X
      #  endif
      #else
      #  if defined (__cplusplus)
      #     define _ASSOCIATIONS_(X)
      #  else
      #     define _ASSOCIATIONS_(X) X
      #  endif
      #endif
      
      ENUM BeNeLux {
        BELGIUM,
        NETHERLANDS,
        LUXEMBURG
      } _ASSOCIATIONS_ (BeNeLux);
      

      另一个sn-p。查看新的#define ENUM

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-27
        • 1970-01-01
        • 1970-01-01
        • 2013-12-23
        • 1970-01-01
        相关资源
        最近更新 更多