digitalmars.D.bugs - extremely subtle D --> C linking bug ... (dmd .139 linux)
- clayasaurus (24/24) Nov 15 2005 This bug was /almost/ a show stopper for me, just because it took so
- clayasaurus (3/78) Nov 15 2005 Just found out it doesn't work if they are all ulong, but it does it
- Regan Heath (16/63) Nov 15 2005 A ulong in D is twice as long as an unsigned long in C (generally).
- clayasaurus (3/79) Nov 15 2005 Thanks, I didn't realize that a unsigned long in C is the same as a uint...
- Mike Parker (9/12) Nov 15 2005 Be careful with this, though. That's on 32-bit systems, where ints and
- Thomas Kuehne (13/26) Nov 18 2005 -----BEGIN PGP SIGNED MESSAGE-----
This bug was /almost/ a show stopper for me, just because it took so long to find it. I attached two files, bug.d, and c_func.cpp. Compile with.. g++ -c c_func.cpp dmd bug.d c_func.o -L-lstdc++ The D version links to this function through extern(C) { void c_func(ushort a, ulong b, int c, ushort d); } and the actual function itself is extern "C" { void c_func(unsigned short a, unsigned long b, int c, unsigned short d) { printf("%d %d %d %d\n", a, b, c, d); } } I call the function with the following arguments... c_func(60000, 0, 0, 60000); And it prints the following... 60000 0 0 0 It can be 'fixed' when you make all the arguments in the function the same type. I really have no clue why this is happening though.
Nov 15 2005
clayasaurus wrote:This bug was /almost/ a show stopper for me, just because it took so long to find it. I attached two files, bug.d, and c_func.cpp. Compile with.. g++ -c c_func.cpp dmd bug.d c_func.o -L-lstdc++ The D version links to this function through extern(C) { void c_func(ushort a, ulong b, int c, ushort d); } and the actual function itself is extern "C" { void c_func(unsigned short a, unsigned long b, int c, unsigned short d) { printf("%d %d %d %d\n", a, b, c, d); } } I call the function with the following arguments... c_func(60000, 0, 0, 60000); And it prints the following... 60000 0 0 0 It can be 'fixed' when you make all the arguments in the function the same type. I really have no clue why this is happening though. ------------------------------------------------------------------------ extern(C) { void c_func(ushort a, ulong b, int c, ushort d); } int main() { c_func(60000, 0, 0, 60000); return 0; } ------------------------------------------------------------------------ #include <stdio.h> extern "C" { void c_func(unsigned short a, unsigned long b, int c, unsigned short d) { printf("%d %d %d %d\n", a, b, c, d); } }Just found out it doesn't work if they are all ulong, but it does it they are all uint.
Nov 15 2005
On Tue, 15 Nov 2005 11:04:18 -0500, clayasaurus <clayasaurus gmail.com> wrote:clayasaurus wrote:A ulong in D is twice as long as an unsigned long in C (generally). For help converting C to D, see: http://www.digitalmars.com/d/type.html http://www.digitalmars.com/d/ctod.html#types In other words, if C says "unsigned long" in D you use "uint". eg. [original.c] void c_func(unsigned short a, unsigned long b, int c, unsigned short d) {} [your.d] extern(C) { void c_func(ushort a, uint b, int c, ushort d); } If however C used "long long" then you'd use D's "long" type. ReganThis bug was /almost/ a show stopper for me, just because it took so long to find it. I attached two files, bug.d, and c_func.cpp. Compile with.. g++ -c c_func.cpp dmd bug.d c_func.o -L-lstdc++ The D version links to this function through extern(C) { void c_func(ushort a, ulong b, int c, ushort d); } and the actual function itself is extern "C" { void c_func(unsigned short a, unsigned long b, int c, unsigned short d) { printf("%d %d %d %d\n", a, b, c, d); } } I call the function with the following arguments... c_func(60000, 0, 0, 60000); And it prints the following... 60000 0 0 0 It can be 'fixed' when you make all the arguments in the function the same type. I really have no clue why this is happening though. ------------------------------------------------------------------------ extern(C) { void c_func(ushort a, ulong b, int c, ushort d); } int main() { c_func(60000, 0, 0, 60000); return 0; } ------------------------------------------------------------------------ #include <stdio.h> extern "C" { void c_func(unsigned short a, unsigned long b, int c, unsigned short d) { printf("%d %d %d %d\n", a, b, c, d); } }Just found out it doesn't work if they are all ulong, but it does it they are all uint.
Nov 15 2005
Regan Heath wrote:On Tue, 15 Nov 2005 11:04:18 -0500, clayasaurus <clayasaurus gmail.com> wrote:Thanks, I didn't realize that a unsigned long in C is the same as a uint in D.clayasaurus wrote:A ulong in D is twice as long as an unsigned long in C (generally). For help converting C to D, see: http://www.digitalmars.com/d/type.html http://www.digitalmars.com/d/ctod.html#typesThis bug was /almost/ a show stopper for me, just because it took so long to find it. I attached two files, bug.d, and c_func.cpp. Compile with.. g++ -c c_func.cpp dmd bug.d c_func.o -L-lstdc++ The D version links to this function through extern(C) { void c_func(ushort a, ulong b, int c, ushort d); } and the actual function itself is extern "C" { void c_func(unsigned short a, unsigned long b, int c, unsigned short d) { printf("%d %d %d %d\n", a, b, c, d); } } I call the function with the following arguments... c_func(60000, 0, 0, 60000); And it prints the following... 60000 0 0 0 It can be 'fixed' when you make all the arguments in the function the same type. I really have no clue why this is happening though. ------------------------------------------------------------------------ extern(C) { void c_func(ushort a, ulong b, int c, ushort d); } int main() { c_func(60000, 0, 0, 60000); return 0; } ------------------------------------------------------------------------ #include <stdio.h> extern "C" { void c_func(unsigned short a, unsigned long b, int c, unsigned short d) { printf("%d %d %d %d\n", a, b, c, d); } }Just found out it doesn't work if they are all ulong, but it does it they are all uint.In other words, if C says "unsigned long" in D you use "uint". eg. [original.c] void c_func(unsigned short a, unsigned long b, int c, unsigned short d) {} [your.d] extern(C) { void c_func(ushort a, uint b, int c, ushort d); } If however C used "long long" then you'd use D's "long" type. Regan
Nov 15 2005
clayasaurus wrote: >Thanks, I didn't realize that a unsigned long in C is the same as a uint in D.Be careful with this, though. That's on 32-bit systems, where ints and longs are almost always the same size from compiler to compiler. On 64-bit systems, I have heard that some compilers treat longs as 64-bit and some do not. The C (and/or C++) spec does not specify anything other than 'a long is at least as big as an int'. When interfacing with C code, always be aware of the properties of the compiler you are using and the platform you are using it on.
Nov 15 2005
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Mike Parker schrieb am 2005-11-16:clayasaurus wrote: >for 64-bit systems: Microsoft - sizeof(int) == sizeof(long) most Posix systems - sizeof(int) * 2 == sizeof(long) And then there are options like GCC's -mlong32 and -mlong64 Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFDfoH93w+/yD4P9tIRAvDDAJwLXILVQA7wx97KO2jjlDNE+hDRiQCaAmpU lfIlwi4Lv2Ku7/Dz9wB8j2I= =F7Zy -----END PGP SIGNATURE-----Thanks, I didn't realize that a unsigned long in C is the same as a uint in D.Be careful with this, though. That's on 32-bit systems, where ints and longs are almost always the same size from compiler to compiler. On 64-bit systems, I have heard that some compilers treat longs as 64-bit and some do not. The C (and/or C++) spec does not specify anything other than 'a long is at least as big as an int'. When interfacing with C code, always be aware of the properties of the compiler you are using and the platform you are using it on.
Nov 18 2005