Jump to page: 1 2
Thread overview
extern(C) enum
Sep 15, 2017
bitwise
Sep 15, 2017
rikki cattermole
Sep 15, 2017
bitwise
Sep 15, 2017
Jonathan M Davis
Sep 15, 2017
bitwise
Sep 15, 2017
Jonathan M Davis
Sep 15, 2017
jmh530
Sep 16, 2017
Jonathan M Davis
Sep 15, 2017
Timothy Foster
Sep 15, 2017
nkm1
Sep 15, 2017
bitwise
Sep 16, 2017
Timothy Foster
Sep 16, 2017
nkm1
Sep 17, 2017
bitwise
Sep 17, 2017
nkm1
Sep 17, 2017
bitwise
Sep 18, 2017
Mike Parker
Sep 18, 2017
bitwise
Sep 18, 2017
Mike Parker
Sep 18, 2017
Moritz Maxeiner
September 15, 2017
I translated the headers for FreeType2 to D, and in many cases, enums are used as struct members.

If I declare an extern(C) enum in D, is it guaranteed to have the same underlying type and size as it would for a C compiler on the same platform?


September 15, 2017
On 15/09/2017 5:15 AM, bitwise wrote:
> I translated the headers for FreeType2 to D, and in many cases, enums are used as struct members.
> 
> If I declare an extern(C) enum in D, is it guaranteed to have the same underlying type and size as it would for a C compiler on the same platform?

No need for extern(C). Be as specific as you need, but most likely you won't need to (e.g. first is automatically 0).

enum Foo : int {
	Start = 0,
	StuffHere
	End
}

September 15, 2017
On Friday, September 15, 2017 04:15:57 bitwise via Digitalmars-d-learn wrote:
> I translated the headers for FreeType2 to D, and in many cases, enums are used as struct members.
>
> If I declare an extern(C) enum in D, is it guaranteed to have the same underlying type and size as it would for a C compiler on the same platform?

extern(C) should have no effect on enums. It's for function linkage, and enums don't even have an address, so they don't actually end up in the program as a symbol. And since C's int and D's int are the same on all platforms that D supports (we'd have c_int otherwise, like we have c_long), any enum with a base type of int (which is the default) will match what's in C.

- Jonathan M Davis

September 15, 2017
On Friday, 15 September 2017 at 06:57:31 UTC, rikki cattermole wrote:
> On 15/09/2017 5:15 AM, bitwise wrote:
>> I translated the headers for FreeType2 to D, and in many cases, enums are used as struct members.
>> 
>> If I declare an extern(C) enum in D, is it guaranteed to have the same underlying type and size as it would for a C compiler on the same platform?
>
> No need for extern(C). Be as specific as you need, but most likely you won't need to (e.g. first is automatically 0).
>
> enum Foo : int {
> 	Start = 0,
> 	StuffHere
> 	End
> }

This is for D/C interop though.

enum E {
    A, B, C
}

struct S {
   E e;
}

So based on the underlying type chosen by each compiler, the size of struct S could change.

I can't strongly type the D enums to match, because I don't know what size the C compiler will make 'E', unless D somehow gauntness the same enum-sizing as the C compiler would.

September 15, 2017
On Friday, 15 September 2017 at 07:24:34 UTC, Jonathan M Davis wrote:
> On Friday, September 15, 2017 04:15:57 bitwise via Digitalmars-d-learn wrote:
>> I translated the headers for FreeType2 to D, and in many cases, enums are used as struct members.
>>
>> If I declare an extern(C) enum in D, is it guaranteed to have the same underlying type and size as it would for a C compiler on the same platform?
>
> extern(C) should have no effect on enums. It's for function linkage, and enums don't even have an address, so they don't actually end up in the program as a symbol. And since C's int and D's int are the same on all platforms that D supports (we'd have c_int otherwise, like we have c_long), any enum with a base type of int (which is the default) will match what's in C.
>
> - Jonathan M Davis

I'm confused...is it only C++ that has implementation defined enum size? I thought that was C as well.

September 16, 2017
On Friday, September 15, 2017 15:35:48 bitwise via Digitalmars-d-learn wrote:
> On Friday, 15 September 2017 at 07:24:34 UTC, Jonathan M Davis
>
> wrote:
> > On Friday, September 15, 2017 04:15:57 bitwise via
> >
> > Digitalmars-d-learn wrote:
> >> I translated the headers for FreeType2 to D, and in many cases, enums are used as struct members.
> >>
> >> If I declare an extern(C) enum in D, is it guaranteed to have the same underlying type and size as it would for a C compiler on the same platform?
> >
> > extern(C) should have no effect on enums. It's for function linkage, and enums don't even have an address, so they don't actually end up in the program as a symbol. And since C's int and D's int are the same on all platforms that D supports (we'd have c_int otherwise, like we have c_long), any enum with a base type of int (which is the default) will match what's in C.
> >
> > - Jonathan M Davis
>
> I'm confused...is it only C++ that has implementation defined enum size? I thought that was C as well.

It is my understanding that for both C and C++, an enum is always an int (unless you're talking about enum classes in C++). The size of an int can change based on your architecture, but AFAIK, all of the architectures supported by D guarantee it it be 32 bits in C/C++ (certainly, all of the architectures supported by dmd do), and druntime would have serious issues if it were otherwise, as it assumes all of the place that D's int is the same as C/C++'s int.

It's certainly possible that my understanding of C/C++ enums is wrong, but if it is, you'd basically be screwed when dealing with any C functions that take an enum in any case that an enum wasn't 32 bits - especially if the C/C++ compiler could choose whatever size it wanted that fit the values.

- Jonathan M Davis

September 15, 2017
On Friday, 15 September 2017 at 18:20:06 UTC, Jonathan M Davis wrote:
>
> It is my understanding that for both C and C++, an enum is always an int (unless you're talking about enum classes in C++). The size of an int can change based on your architecture, but AFAIK, all of the architectures supported by D guarantee it it be 32 bits in C/C++ (certainly, all of the architectures supported by dmd do), and druntime would have serious issues if it were otherwise, as it assumes all of the place that D's int is the same as C/C++'s int.
>
> It's certainly possible that my understanding of C/C++ enums is wrong, but if it is, you'd basically be screwed when dealing with any C functions that take an enum in any case that an enum wasn't 32 bits - especially if the C/C++ compiler could choose whatever size it wanted that fit the values.
>
> - Jonathan M Davis

Not to hijack the thread, but is there anything about enums that can't be done with a struct? The code below is just a simple example that I'm sure I could complicate unnecessarily to re-create much of the behavior of current enums with the syntax of std.tuple.

I suppose what I'm wondering how E.B below is treated in the writeln. With an enum, it would be a manifest constant. Does static initialization of the struct do the same thing?

struct Enum(T)
{
    T A;
    T B;
}

static Enum!int E = {A:0, B:1};

void main()
{
    import std.stdio : writeln;

    writeln(E.B);
}
September 15, 2017
On Friday, 15 September 2017 at 15:35:48 UTC, bitwise wrote:
> On Friday, 15 September 2017 at 07:24:34 UTC, Jonathan M Davis wrote:
>> On Friday, September 15, 2017 04:15:57 bitwise via Digitalmars-d-learn wrote:
>>> I translated the headers for FreeType2 to D, and in many cases, enums are used as struct members.
>>>
>>> If I declare an extern(C) enum in D, is it guaranteed to have the same underlying type and size as it would for a C compiler on the same platform?
>>
>> extern(C) should have no effect on enums. It's for function linkage, and enums don't even have an address, so they don't actually end up in the program as a symbol. And since C's int and D's int are the same on all platforms that D supports (we'd have c_int otherwise, like we have c_long), any enum with a base type of int (which is the default) will match what's in C.
>>
>> - Jonathan M Davis
>
> I'm confused...is it only C++ that has implementation defined enum size? I thought that was C as well.

I believe C enum size is implementation defined. A C compiler can pick the underlying type (1, 2, or 4 bytes, signed or unsigned) that fits the values in the enum.

A D int is always the same size as a C int because C ints are 4 bytes on 32bit and above architectures and D doesn't support architectures below 32bit so you never run into a case where a C int is 2 bytes.

D can't guarantee that the size of an extern(C) enum will match an arbitrary C compiler's choice, so I'm pretty sure it'll just default to a D int.

It's further likely that padding in a struct will differ between C compilers so if you need a D struct to be the same size as a C struct in every case... welp that's not exactly going to be fun.
September 15, 2017
On Friday, 15 September 2017 at 19:21:02 UTC, Timothy Foster wrote:
> I believe C enum size is implementation defined. A C compiler can pick the underlying type (1, 2, or 4 bytes, signed or unsigned) that fits the values in the enum.

No, at least, not C99. See 6.4.4.3: "An identifier declared as an enumeration constant has type int". You must be thinking about C++.
September 15, 2017
On Friday, 15 September 2017 at 19:35:50 UTC, nkm1 wrote:
> On Friday, 15 September 2017 at 19:21:02 UTC, Timothy Foster wrote:
>> I believe C enum size is implementation defined. A C compiler can pick the underlying type (1, 2, or 4 bytes, signed or unsigned) that fits the values in the enum.
>
> No, at least, not C99. See 6.4.4.3: "An identifier declared as an enumeration constant has type int". You must be thinking about C++.

Thanks - this works for me. The bindings are for an open source C library. So I guess I'm safe as long as I can be sure I'm using a C99 compiler and strongly typing as int in D.

C++ seems to be a much more complicated situation, but it appears that for 'enum class' or 'enum struct' the underlying type is int, even when it's not specified.


ยง 7.2:

[1] "The enum-keys enum class and enum struct are semantically equivalent; an enumeration type declared with one of these is a scoped enumeration, and its enumerators are scoped enumerators."

[2] "For a scoped enumeration type, the underlying type is int if it is not explicitly specified."

[1][2] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf

Shame that even relatively new C++ code tends to use unscoped enums.

« First   ‹ Prev
1 2