grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Off-topic] C++ enums


From: Isaac Dupree
Subject: [Off-topic] C++ enums
Date: Tue, 16 Feb 2010 13:47:35 -0500
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.7) Gecko/20100120 Shredder/3.0.1

On 02/16/10 13:15, address@hidden wrote:
On Tue, Feb 16, 2010 at 12:03 PM, Isaac Dupree
<address@hidden>  wrote:
On 02/16/10 10:52, Michal Suchanek wrote:

enum allows it just fine

Not here:

typedef enum t1 { BTI1 = 1,

typo, should be "BIT1". then it works. (In C.  Also remember not to get
confused by the fact that it doesn't work in C++, for type-related reasons

Says who?

OK, I guess I'll get into it, since you asked...

Comeau is perfectly happy with this code, in strict C++ mode:

enum flags
{
   BIT1 = 1,
   BIT2 = 2,
   BIT12 = BIT1 | BIT2
};

In C and C++, enums are their own type distinct from int. In C, there exist implicit conversions both from and to all enum types and int. In C++, there only exist implicit conversions from enum types to int. Bitwise and arithmetic operators only operate on int, not enum types (unless a C++ operator overload is declared); these operators appear to work with enums because of all the implicit conversion.

Your example works even in C++ because the right-hand side of an "=" in an enum-declaration is of type int, rather than the enum type (as you can see from the fact that you can put "1" there as well). Now BIT1, BIT2, and BIT12 are all (in C++) values (rvalues) of type "flags" (note this does not apply to the left-hand sides in the enum declaration that define their constant values, but it does apply to those right-hand sides).

Now try and combine your with this main function:

int main(int argc, char** argv) {
        flags foo1 = BIT1; // fine
        flags foo12 = BIT12; // fine
        int   bar = BIT1 | BIT2; // fine
        flags baz = BIT1 | BIT2; // error
        return 0 ;
}

(If you want to see it compile in C, add "typedef enum flags flags;" before main().)

See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.19 for some discussion by a C++ expert. And then return to GRUB2 coding where none of this matters. The only weird thing about enums in C is that they're not guaranteed by the standard to be isomorphic to type "int"; each enum might correspond to a different-size, (possibly even different-signedness), integral type, if this is possible given the range of values in the particular "enum{...};" declaration. (This weird thing also affects C++ but I omitted it in the above explanation of enum versus integral types.)

-Isaac




reply via email to

[Prev in Thread] Current Thread [Next in Thread]