does the enum hack work in C? If so, is it supposed to work in VisualStudio 2003?

StackOverflow https://stackoverflow.com/questions/17997845

  •  04-06-2022
  •  | 
  •  

سؤال

I hate defines. In the quest of eliminating as many of them as possible from an old code base, I need to rely on the enum-hack for defining structures containing arrays. Unfortunately, I'm not getting it to compile when the incriminated .h file gets included by C projects.

typedef struct _P_O {
    enum { MAXELEMENTS=10 };
    P_O_U elem;
    ULONG id[MAXELEMENTS];
    USHORT nid;
} P_O, *PP_O;

this produces error C2208:

'type' : no members defined using this type
An identifier resolving to a type name is in an aggregate declaration, but the compiler cannot declare a member.

OT: I hate using a compiler which is 10 y.o., having to mantain old c code and bad design too; not just defines :)

هل كانت مفيدة؟

المحلول

Given the code in the question, GCC warns: warning: declaration does not declare anything for the enum line.

Place the enum outside the struct and you'll be fine.

typedef int P_O_U;
typedef unsigned long ULONG;
typedef unsigned short USHORT;

enum { MAXELEMENTS = 10 };

typedef struct _P_O
{
    P_O_U  elem;
    ULONG  id[MAXELEMENTS];
    USHORT nid;
} P_O, *PP_O;

نصائح أخرى

struct foo {
    enum { MAXELEMENTS=10 };
    long id[MAXELEMENTS];
};

enum hack like this is valid in C (But not a good style of code, see @Jonathan Leffler's comment). Because when id is defined, MAXELEMENTS qualifies with enumeration constant.

C99 6.2.1 Scopes of identifiers

Structure, union, and enumeration tags have scope that begins just after the appearance of the tag in a type specifier that declares the tag. Each enumeration constant has scope that begins just after the appearance of its defining enumerator in an enumerator list. Any other identifier has scope that begins just after the completion of its declarator.

And an enumeration is a type of integer constant.

C99 6.6 Constant expressions

An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.

Finally, an integer constant can be used in array declarators, see C99 6.7.5.2 Array declarators .That's not surprising.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top