rfg@lupine.ncd.com (Ron Guilmette) (05/12/91)
I may have asked this question once already (long ago). If so I apologize. I forgot the answer. Are either or both of these examples legal? enum E { red, green = sizeof (enum E), blue }; struct S { int i; int j : sizeof (struct S); int k; };
henry@zoo.toronto.edu (Henry Spencer) (05/14/91)
In article <5506@lupine.NCD.COM> rfg@lupine.ncd.com (Ron Guilmette) writes: >Are either or both of these examples legal? > >enum E { red, green = sizeof (enum E), blue }; >struct S { int i; int j : sizeof (struct S); int k; }; I think neither. In the first one, the argument of sizeof is meaningless, because E is not declared until the end of the brace-enclosed list. Enums, unlike structs and unions, cannot be incomplete types. In the second example, the struct type is incomplete until the closing brace. ANSI C is rather vague about where incomplete types can be used, saying only "when the size of an object of the specified type is not needed", with no explanation of what that *means*, but sizeof is the one clear situation. -- And the bean-counter replied, | Henry Spencer @ U of Toronto Zoology "beans are more important". | henry@zoo.toronto.edu utzoo!henry
blodgett@apollo.HP.COM (Bruce Blodgett) (05/17/91)
In article <1991May13.175830.7143@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes: >In article <5506@lupine.NCD.COM> rfg@lupine.ncd.com (Ron Guilmette) writes: >>Are either or both of these examples legal? >> >>enum E { red, green = sizeof (enum E), blue }; >>struct S { int i; int j : sizeof (struct S); int k; }; > >I think neither. > >In the first one, the argument of sizeof is meaningless, because E is not >declared until the end of the brace-enclosed list. Enums, unlike structs >and unions, cannot be incomplete types. Section 3.1.2.1 states: "enumeration tags have scope that begins just aftert the appearance of the tag in a type specifier that declares the tag." So enum tag E is in scope at the sizeof(enum E). Section 3.3.3.4 lists the following Constraint: "The sizeof operator shall not be applied to an expression that has ... an incomplete type" The question becomes, "does enum E have incomplete type inside its enumerator-list?" Section 3.1.2.5 defines incomplete types as: "types that describe objects but lack information needed to determine their sizes". The question becomes, "does enum E lack information needed to determine its size inside its enumerator-list?" Section 3.5.2.2 states: "Each enumerated type shall be compatible with an integer type; the choice of type is implementation-defined." The implementation could choose exactly one integral type with which to make all enumerated types compatible. In this case, enum E has enough information to determine its size inside its enumerator-list. Alternately, the implementation could tailor each enumerated type to be the smallest integral type sufficient to store any of its member's values (to save on disk space). In this case, enum E does NOT have enough information to determine its size inside its enumerator-list. Therefore the definition enum E { red, green = sizeof (enum E), blue }; relies upon implementation-defined behavior. Bruce Blodgett blodgett@apollo.hp.com (508) 256-0176 x4037
henry@zoo.toronto.edu (Henry Spencer) (05/19/91)
In article <519a28cf.20b6d@apollo.HP.COM> blodgett@apollo.HP.COM (Bruce Blodgett) writes: >>>enum E { red, green = sizeof (enum E), blue }; >Section 3.1.2.1 states: >"enumeration tags have scope that begins just aftert the appearance of >the tag in a type specifier that declares the tag." Hmm, you're right, I missed that one. >The question becomes, "does enum E have incomplete type inside its >enumerator-list?" > >Section 3.1.2.5 defines incomplete types as: >"types that describe objects but lack information needed to determine >their sizes". No, that phrase appears to be an informal description rather than a precise definition. The standard never defines what information is needed to determine sizes; it merely describes two specific constructs (array without dimension and struct/union without declaration list) that generate incomplete types. In fact, in the discussion of tags (3.5.2.3) there is a footnote indicating that the committee thought it was clear that enums could not be incomplete. Certainly there is no discussion for enum analogous to that for struct/union about how an incomplete type comes into existence. (That same footnote indicates that they thought other types could not depend on the details of the declaration of an enumerated type, which is, of course, wrong when sizeof comes into the picture.) I don't think the matter can be settled cleanly by reference to the existing standard. Some ambitious soul might want to submit a request for a formal interpretation. However, there does seem to be trouble lurking here for an implementation that tries to custom-tailor the sizes of enumerated types. >Therefore the definition > enum E { red, green = sizeof (enum E), blue }; >relies upon implementation-defined behavior. No, it relies on behavior that is not clearly specified by the standard. "Implementation defined" has a specific meaning in ANSI-C-speak, and this isn't it. It would probably be better to assume that the relevant behavior is undefined, meaning that anything can happen and users should avoid the construct entirely. -- And the bean-counter replied, | Henry Spencer @ U of Toronto Zoology "beans are more important". | henry@zoo.toronto.edu utzoo!henry
enag@ifi.uio.no (Erik Naggum) (05/20/91)
Ron Guilmette writes: | | Are either or both of these examples legal? | | enum E { red, green = sizeof (enum E), blue }; I think I may be missing something vital in your question. What is "sizeof (enum E)" supposed to return if not the same as "sizeof (int)"? </Erik> -- Erik Naggum Professional Programmer +47-2-836-863 Naggum Software Electronic Text <enag@ifi.uio.no> 0118 OSLO, NORWAY Computer Communications <erik@naggum.uu.no>
diamond@jit533.swstokyo.dec.com (Norman Diamond) (05/20/91)
In article <ENAG.91May20004919@maud.ifi.uio.no> enag@ifi.uio.no (Erik Naggum) writes: >Ron Guilmette writes: >> enum E { red, green = sizeof (enum E), blue }; > >What is "sizeof (enum E)" supposed to return if not the same as >"sizeof (int)"? sizeof (short), sizeof (long), or sizeof (other_integral_type_which_the_\ implementation_is_allowed_to_define_even_though_portable_programs_cannot_\ directly_name_this_type) -- Norman Diamond diamond@tkov50.enet.dec.com If this were the company's opinion, I wouldn't be allowed to post it. Permission is granted to feel this signature, but not to look at it.
enag@ifi.uio.no (Erik Naggum) (05/20/91)
Erik Naggum writes: | | What is "sizeof (enum E)" supposed to return if not the same as | "sizeof (int)"? Norman Diamond writes: | | sizeof (short), sizeof (long), or sizeof (other_integral_type_which_the_\ | implementation_is_allowed_to_define_even_though_portable_programs_cannot_\ | directly_name_this_type) Right. There's a subtle difference between the type of enumerators and the enumeration type itself. Section 3.5.2.2 of dpANS of 1/11/88 (sorry, I have the proper standard at my office) specifies that the former have type int, while the enumerated type "shall be compatible with an integer type; the choice of type is implementation-defined". (Why this is so escapes me.) </Erik> -- Erik Naggum Professional Programmer +47-2-836-863 Naggum Software Electronic Text <enag@ifi.uio.no> 0118 OSLO, NORWAY Computer Communications <erik@naggum.uu.no>
diamond@jit533.swstokyo.dec.com (Norman Diamond) (05/21/91)
Erik Naggum writes: >| What is "sizeof (enum E)" supposed to return if not the same as >| "sizeof (int)"? Norman Diamond writes: >| sizeof (short), sizeof (long), or sizeof (other_integral_type...) Erik Naggum: >Right. There's a subtle difference between the type of enumerators >and the enumeration type itself. ... the former have type int, while >the enumerated type "shall be compatible with an integer type; the choice >of type is implementation-defined". (Why this is so escapes me.) Variables can be declared with the enumeration type, and their storage requirements are determined accordingly. But enumerators are just constants. The constants 5200 and 'x', for example, have type int, even though they can fit in shorts; but they're just constants and aren't necessarily stored. -- Norman Diamond diamond@tkov50.enet.dec.com If this were the company's opinion, I wouldn't be allowed to post it. Permission is granted to feel this signature, but not to look at it.