Thread overview
Shouldn't c_long and c_ulong be library typedefs?
Sep 05, 2012
Andrej Mitrovic
Sep 06, 2012
bearophile
Sep 06, 2012
Andrej Mitrovic
Sep 06, 2012
Andrej Mitrovic
Sep 06, 2012
Mehrdad
September 05, 2012
I'm interfacing with C++ and found a little overload problem:

C++:
void test(unsigned int x)  { }
void test(unsigned long x) { }

int main()
{
    unsigned int x;
    unsigned long y;
    test(x);
    test(y);
    return 0;
}

No problem, but in D:

import core.stdc.config;
void test(uint x)  { }
void test(c_ulong x) { }

void main()
{
    uint x;
    c_ulong y;
    test(x);
    test(y);
}

test.d(12): Error: function test.test called with argument types:
	((uint))
matches both:
	test.test(uint x)
and:
	test.test(uint x)

c_ulong is an alias to either uint or ulong based on the architecture. But it is an *alias*, meaning you can't overload it like the above based on the architecture. This leads to cases where compiling on one architecture works (x64 -> c_ulong is D ulong, overloads with uint) but on another one it doesn't (x32 -> c_ulong is D uint, can't overload with uint).

Anyway I've two questions:
1) Has anyone come up with a library solution for a typedef because I
need it for cases like these, and
2) Will c_long/c_ulong be converted to a library typedef or will they
remain aliases?
September 06, 2012
Andrej Mitrovic:

> 1) Has anyone come up with a library solution for a typedef because I need it for cases like these, and
> 2) Will c_long/c_ulong be converted to a library typedef or will they remain aliases?

In Phobos there is a Typedef, but it's unusable :-(

Bye,
bearophile
September 06, 2012
On 9/6/12, bearophile <bearophileHUGS@lycos.com> wrote:
> In Phobos there is a Typedef, but it's unusable :-(

I forgot to mention, I'm using GDC which is based on 2.059 or earlier, and which can't compile the Typedef in 2.060 Phobos due to an ICE.

On 9/6/12, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> I'd always expect them to be aliases.
> I'm fairly sure that the C
> linker is going to see any difference between int and long either if long is
> the same size as int

Sorry, I should have been more clear. :)
I'm aware of linker issues but this is handled by uniquely naming
extern(C) functions. Here's an example of how a D virtual would be
invoked:

extern(C) void test__1234_0001(void* d_object, uint* val)
{
    (cast(SomeClass)d_object).test(val);
}

extern(C) void test__1234_0002(void* d_object, c_ulong* val)
{
    (cast(SomeClass)d_object).test(val);
}
September 06, 2012
On 9/6/12, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> On 9/6/12, bearophile <bearophileHUGS@lycos.com> wrote:
>> In Phobos there is a Typedef, but it's unusable :-(
>
> I forgot to mention, I'm using GDC which is based on 2.059 or earlier, and which can't compile the Typedef in 2.060 Phobos due to an ICE.

Anyway here's a temporary workaround:

static import core.stdc.config;
struct c_long
{
    core.stdc.config.c_long val;
    alias val this;
}

struct c_ulong
{
    core.stdc.config.c_ulong val;
    alias val this;
}

I should have posted all of this to D.learn not here, sorry.
September 06, 2012
On Wednesday, 5 September 2012 at 23:51:41 UTC, Andrej Mitrovic wrote:
> I'm interfacing with C++ and found a little overload problem:
>
> C++:
> void test(unsigned int x)  { }
> void test(unsigned long x) { }
>
> int main()
> {
>     unsigned int x;
>     unsigned long y;
>     test(x);
>     test(y);
>     return 0;
> }
>
> No problem, but in D:
>
> import core.stdc.config;
> void test(uint x)  { }
> void test(c_ulong x) { }
>
> void main()
> {
>     uint x;
>     c_ulong y;
>     test(x);
>     test(y);
> }
>
> test.d(12): Error: function test.test called with argument types:
> 	((uint))
> matches both:
> 	test.test(uint x)
> and:
> 	test.test(uint x)
>
> c_ulong is an alias to either uint or ulong based on the architecture.
> But it is an *alias*, meaning you can't overload it like the above
> based on the architecture. This leads to cases where compiling on one
> architecture works (x64 -> c_ulong is D ulong, overloads with uint)
> but on another one it doesn't (x32 -> c_ulong is D uint, can't
> overload with uint).
>
> Anyway I've two questions:
> 1) Has anyone come up with a library solution for a typedef because I
> need it for cases like these, and
> 2) Will c_long/c_ulong be converted to a library typedef or will they
> remain aliases?



I was complaining about something similar way back when (I was saying size_t should not be the same data type as uint) but the idea got thrown in the trash.