【问题标题】:C - forward declaration of enums?C - 枚举的前向声明?
【发布时间】:2011-11-20 18:25:15
【问题描述】:

C 中枚举的前向声明对我不起作用。我搜索了互联网和 *,但所有关于枚举数前向声明的问题都涉及 c++。你在 C 中声明枚举数是怎么做的?将它们放在每个文件的顶部(或包含在其中),以便文件中的所有函数都可以访问它们?谢谢

【问题讨论】:

  • 通常包含在一个包含中,您能否向我们展示代码以查看您遇到的问题是什么?

标签: c enums enumeration forward-declaration


【解决方案1】:

将它们放在头文件中,以便所有需要它们的文件都可以访问头文件并使用其中的声明。

使用选项编译时:

$ /usr/bin/gcc -g -std=c99 -Wall -Wextra -c enum.c
$

GCC 4.2.1(在 MacOS X 10.7.1 上)接受以下代码:

enum xyz;

struct qqq { enum xyz *p; };

enum xyz { abc, def, ghi, jkl };

添加-pedantic,它会发出警告:

$ /usr/bin/gcc -g -std=c99 -Wall -Wextra -pedantic -c enum.c
enum.c:1: warning: ISO C forbids forward references to ‘enum’ types
enum.c:5: warning: ISO C forbids forward references to ‘enum’ types
$

因此,您不应该尝试在 C 中使用枚举类型的前向声明; GCC 允许它在不被逼迂腐的情况下作为扩展。

【讨论】:

  • 为什么 ISO C 严格禁止对“枚举”类型的前向引用?
  • 因为在编译器知道定义之前,它无法确定需要多大的存储空间。可以将值存储在 1 字节整数 (char) 中,也可能需要 2 或 4 字节。
【解决方案2】:

您不能“前向声明”枚举,因为编译器不知道枚举的大小。 C 标准规定“每个枚举类型应与 char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,但应能够表示所有成员的值枚举"。

【讨论】:

  • 这是不是更有可能是不允许的,因为它根本没有任何采摘棉花的意义!在告诉编译器它们是什么之前,您不能引用任何枚举 NAMES。没有定义名称的枚举有什么用途?
  • @luser:您几乎可以证明指向不完整枚举的指针(如我的示例代码中所示)具有某种意义。但它非常脆弱——你的结论是,当不完整时它们基本上没有实际用途是正确的。
  • @luserdroog 您可以在头文件中使用结构的不完整定义,因此同样您可以在其他地方的定义支持的枚举的不完整定义,并且在每个点都包含该定义使用枚举值。
  • @luserdroog。我的用例是(在标题中):enum Foo { ... }; enum Bar; enum Foo bar2foo( Bar bar ); 所以我们声明了返回 Foo 的函数。如果你想使用它,你还需要包含 Foo 的定义。
  • 这不是论据。 typedef struct S S; 有效,但 typedef enum E E; 无效,尽管两者都有未定义的大小。实际上,前向声明只是知道所涉及实体的大小。
【解决方案3】:

我来到这里时遇到了同样的错误,但这里提供的关于代码/错误的信息并不多。

我的 Makefile 标志是:-Wall -Wextra -Werror -pedantic -std=c17

在我的标题中,我有以下enum

typedef enum 
{
  IS_HEAD = 1, 
  IS_VALUE = 2,
  IS_SIDE
} CoinResult;

教程herethere

建议使用这样的东西:

enum CoinResult cr;
cr = IS_SIDE;

这会导致 OP 声明的错误。

通过使用解决:

CoinResult cr = IS_SIDE; 

不确定使用的是哪个 C 标准、代码或参考 OP,但我有点同意:针对这个相对简单的问题的大多数教程和解决方案都有些模棱两可。

【讨论】:

    【解决方案4】:

    CoinResult 不是枚举,它是一种类型。如果你有

    enum CoinResult {
        IS_HEAD = 1,
        IS_VALUE = 2,
        IS_SIDE,
    };
    

    然后

        enum CoinResult cr;
    

    应该是正确的。

    【讨论】: