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

これを C++ コンパイラでコンパイルしようとするとエラーが発生しますが、C コンパイラでは問題なく動作するようです。そこで質問です。C ++で列挙型をパックすることは可能ですか、またはエラーが発生する理由を誰かが見ることができますか?

エラーは次のとおりです。

「BeNeLux の宣言後にセミコロンがありません」。

チェックして再チェックした後、コードの残りの部分で必要な場所にセミコロンが確実にあることがわかりました。

補遺:

_PACKAGE_はほんの一例でした。改名しています。

_ASSOCIATIONS_は BeNeLux のタイプではありません:

#define _ASSOCIATIONS_ __attribute__((packed))

コードは改ざんされていますが、それが 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 は使用できません。プログラムによる解決策を探しています。

4

7 に答える 7

4

アップデート:

C ++ 11以降では、基になるタイプのを指定できますenum。例えば:

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、そのアドレスを使用しようとしない限り、整数値に変数を割り当てることさえしません。

于 2010-05-25T17:28:37.077 に答える
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)

于 2010-05-25T16:56:46.990 に答える
1

ここには本当のブレークスルーはありません。あなたのコンパイラがそれをより良くしてくれることを期待して、私は物事を並べ替えただけです. あなたのバージョンの 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
于 2010-05-26T04:13:57.223 に答える
0

C ++では、は必要ありませんtypedef。から始めてenum BeNeLuxください。同じ識別子を持つ型と変数を宣言することは、いずれかの言語で合法ではない可能性もあります(私は決して覚えていません)。

于 2010-05-07T21:41:56.897 に答える
0
enum BeNeLux
{
   BELGIUM,
   NETHERLANDS,
   LUXEMBURG
};

これは、C++コードに期待されることです。

于 2010-05-07T21:43:35.427 に答える
0

GCC と G++ を使用していると思います。私にとって、コードはどちらでも問題なくコンパイルされます。特定のコンパイラで C++ を有効にすると、このような機能がなくなるのは驚くべきことです。

あなたのがC++コード用に編集されて#defineいないことを確認してください。#if#ifndef __cplusplus

g++ -Eプリプロセッサの出力を確認して、が表示されることを確認してください#define

また、プリプロセッサ マクロの場合でも、アンダースコアと大文字または 2 つのアンダースコアで始まる名前は、コンパイラとライブラリ用に予約されています。マクロが必要な場合は、PACKEDが最適な名前かもしれません。

于 2010-05-07T21:18:01.207 に答える
0
#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);

別のスニペット。新しいものを見る#define ENUM

于 2010-05-26T19:17:16.560 に答える