www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Interfacing with c and platform dependent sizes

reply simendsjo <simen.endsjo pandavre.com> writes:
C is not my strong side, so I'm having some problems wrapping some code.

I found a couple of sources on this:
1) http://www.digitalmars.com/d/2.0/htomodule.html
2) http://www.digitalmars.com/d/2.0/interfaceToC.html

1)
C's long is the same as D's int.
long long is long

2)
C 32bit's long long is D's long, C 64 bits long is D's long.

So.. A long in C is the same as the platform size? And long long doesn't 
exist in 64 bit?
Feb 25 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
simendsjo:

 So.. A long in C is the same as the platform size? And long long doesn't 
 exist in 64 bit?

In D the size of int/uint is 32 bits and long/ulong is 64 bits. In C the size of int, unsigned int, long, long long int, unsigned long long int, etc are not fixed, the change according to the CPU. sizeof(int) <= sizeof(long) <= sizeof(long long). A help: http://www.digitalmars.com/d/2.0/phobos/std_stdint.html Bye, bearophile
Feb 25 2011
next sibling parent reply simendsjo <simen.endsjo pandavre.com> writes:
On 26.02.2011 02:06, bearophile wrote:
 simendsjo:

 So.. A long in C is the same as the platform size? And long long doesn't
 exist in 64 bit?

In D the size of int/uint is 32 bits and long/ulong is 64 bits. In C the size of int, unsigned int, long, long long int, unsigned long long int, etc are not fixed, the change according to the CPU. sizeof(int)<= sizeof(long)<= sizeof(long long). A help: http://www.digitalmars.com/d/2.0/phobos/std_stdint.html Bye, bearophile

Ouch.. Any tips on porting C code that would work nicely with a transition to 64 bit? Should I change all long and int to int_atleast_32_t and long long to 64?
Feb 25 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, February 25, 2011 17:35:02 Jonathan M Davis wrote:
 On Friday, February 25, 2011 17:16:31 simendsjo wrote:
 On 26.02.2011 02:06, bearophile wrote:
 simendsjo:
 So.. A long in C is the same as the platform size? And long long
 doesn't exist in 64 bit?

In D the size of int/uint is 32 bits and long/ulong is 64 bits. In C the size of int, unsigned int, long, long long int, unsigned long long int, etc are not fixed, the change according to the CPU. sizeof(int)<= sizeof(long)<= sizeof(long long). A help: http://www.digitalmars.com/d/2.0/phobos/std_stdint.html Bye, bearophile

Ouch.. Any tips on porting C code that would work nicely with a transition to 64 bit? Should I change all long and int to int_atleast_32_t and long long to 64?

It depends entirely on what the code is doing. It could be completely safe to convert all ints, longs, and long longs to long to long. Or you may have to choose int or long depending on what system the code is supposed to be for. In many cases, using a larger type wouldn't matter, since it can hold more than the smaller type, so whether the type in C/C++ was 32 bits or 64 bits is irrelevant. In other cases, the type needs to be an exact size, because the code is doing bit shifts or whatnot (in which case they _should_ have been using int32_t and int64_t on Linux and whatever the equivalent is on Windows, but unfortunately, many programmers don't). And if you're dealing with a struct, it's possible that that struct has to be an exact size (e.g. for some binary format), and using the wrong type in converting could make it the wrong size. If you want to know what the appropriate D type is for the C/C++ code, you _need_ to know what it does. Now, IIRC, int is almost guaranteed to be 32 bits at this point, and long long is essentially guaranteed to be 64 bits, but long varies from system to system - both in terms of OS and architecture. IIRC, long is 32 bits on Solaris and Windows - both on x86 and x86_64 - but it's 32 bits in x86 Linux and 64 bits in x86_64 Linux. So, if all the code uses is int and long long, then it's probably reasonably safe to use int for int and long for long long, but it's ultimately system dependent. Personally, I would argue that C/C++ code should use int when you don't care about the size of an integral type and use the intX_t types (where X is 8, 16, 32, or 64) when you _do_ care about the size, but there's no guarantee that programmers are going to be that disciplined about it. In any case, if you really don't know the code and don't want to take the time to understand it, I'd use int for int, long for long long, and then if they have long, I'd do the research to figure out which OS and architecture the code is supposed to be for and use int if long long is 32 bits and long if it's 64 bits. If you don't know what system it was built for, then I'd probably just use long and hoped that they weren't doing anything that made using an integral type which was too large a problem.

Actually, I just realized that I was thinking in terms of porting C++ code to D. You're going to have to be more strict if you're just converting header files. However, what you can do is just compile something like this in C/C++ on your system: printf("int -> %d bytes", sizeof(int)); printf("long -> %d bytes", sizeof(long)); printf("long long -> %d bytes", sizeof(long long)); Then you'll know what they are on your system, and you can convert them over just fine. You just have to remember to do the same on any other system that you compile your code on. Bleh. At least D went the route of standarizing the size of its primitive types. - Jonathan M Davis
Feb 25 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-02-26 02:35, Jonathan M Davis wrote:
 On Friday, February 25, 2011 17:16:31 simendsjo wrote:
 On 26.02.2011 02:06, bearophile wrote:
 simendsjo:
 So.. A long in C is the same as the platform size? And long long doesn't
 exist in 64 bit?

In D the size of int/uint is 32 bits and long/ulong is 64 bits. In C the size of int, unsigned int, long, long long int, unsigned long long int, etc are not fixed, the change according to the CPU. sizeof(int)<= sizeof(long)<= sizeof(long long). A help: http://www.digitalmars.com/d/2.0/phobos/std_stdint.html Bye, bearophile

Ouch.. Any tips on porting C code that would work nicely with a transition to 64 bit? Should I change all long and int to int_atleast_32_t and long long to 64?

It depends entirely on what the code is doing. It could be completely safe to convert all ints, longs, and long longs to long to long. Or you may have to choose int or long depending on what system the code is supposed to be for. In many cases, using a larger type wouldn't matter, since it can hold more than the smaller type, so whether the type in C/C++ was 32 bits or 64 bits is irrelevant. In other cases, the type needs to be an exact size, because the code is doing bit shifts or whatnot (in which case they _should_ have been using int32_t and int64_t on Linux and whatever the equivalent is on Windows, but unfortunately, many programmers don't). And if you're dealing with a struct, it's possible that that struct has to be an exact size (e.g. for some binary format), and using the wrong type in converting could make it the wrong size. If you want to know what the appropriate D type is for the C/C++ code, you _need_ to know what it does. Now, IIRC, int is almost guaranteed to be 32 bits at this point, and long long is essentially guaranteed to be 64 bits, but long varies from system to system - both in terms of OS and architecture. IIRC, long is 32 bits on Solaris and Windows - both on x86 and x86_64 - but it's 32 bits in x86 Linux and 64 bits in x86_64 Linux. So, if all the code uses is int and long long, then it's probably reasonably safe to use int for int and long for long long, but it's ultimately system dependent. Personally, I would argue that C/C++ code should use int when you don't care about the size of an integral type and use the intX_t types (where X is 8, 16, 32, or 64) when you _do_ care about the size, but there's no guarantee that programmers are going to be that disciplined about it.

A C "long" is 64bit long on Solaris 64bit according to this: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models
 In any case, if you really don't know the code and don't want to take the time
 to understand it, I'd use int for int, long for long long, and then if they
have
 long, I'd do the research to figure out which OS and architecture the code is
 supposed to be for and use int if long long is 32 bits and long if it's 64
bits.
 If you don't know what system it was built for, then I'd probably just use long
 and hoped that they weren't doing anything that made using an integral type
 which was too large a problem.

 - Jonathan M Davis

-- /Jacob Carlborg
Feb 26 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, February 25, 2011 17:16:31 simendsjo wrote:
 On 26.02.2011 02:06, bearophile wrote:
 simendsjo:
 So.. A long in C is the same as the platform size? And long long doesn't
 exist in 64 bit?

In D the size of int/uint is 32 bits and long/ulong is 64 bits. In C the size of int, unsigned int, long, long long int, unsigned long long int, etc are not fixed, the change according to the CPU. sizeof(int)<= sizeof(long)<= sizeof(long long). A help: http://www.digitalmars.com/d/2.0/phobos/std_stdint.html Bye, bearophile

Ouch.. Any tips on porting C code that would work nicely with a transition to 64 bit? Should I change all long and int to int_atleast_32_t and long long to 64?

It depends entirely on what the code is doing. It could be completely safe to convert all ints, longs, and long longs to long to long. Or you may have to choose int or long depending on what system the code is supposed to be for. In many cases, using a larger type wouldn't matter, since it can hold more than the smaller type, so whether the type in C/C++ was 32 bits or 64 bits is irrelevant. In other cases, the type needs to be an exact size, because the code is doing bit shifts or whatnot (in which case they _should_ have been using int32_t and int64_t on Linux and whatever the equivalent is on Windows, but unfortunately, many programmers don't). And if you're dealing with a struct, it's possible that that struct has to be an exact size (e.g. for some binary format), and using the wrong type in converting could make it the wrong size. If you want to know what the appropriate D type is for the C/C++ code, you _need_ to know what it does. Now, IIRC, int is almost guaranteed to be 32 bits at this point, and long long is essentially guaranteed to be 64 bits, but long varies from system to system - both in terms of OS and architecture. IIRC, long is 32 bits on Solaris and Windows - both on x86 and x86_64 - but it's 32 bits in x86 Linux and 64 bits in x86_64 Linux. So, if all the code uses is int and long long, then it's probably reasonably safe to use int for int and long for long long, but it's ultimately system dependent. Personally, I would argue that C/C++ code should use int when you don't care about the size of an integral type and use the intX_t types (where X is 8, 16, 32, or 64) when you _do_ care about the size, but there's no guarantee that programmers are going to be that disciplined about it. In any case, if you really don't know the code and don't want to take the time to understand it, I'd use int for int, long for long long, and then if they have long, I'd do the research to figure out which OS and architecture the code is supposed to be for and use int if long long is 32 bits and long if it's 64 bits. If you don't know what system it was built for, then I'd probably just use long and hoped that they weren't doing anything that made using an integral type which was too large a problem. - Jonathan M Davis
Feb 25 2011
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 25 Feb 2011 20:06:04 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 simendsjo:

 So.. A long in C is the same as the platform size? And long long doesn't
 exist in 64 bit?

In D the size of int/uint is 32 bits and long/ulong is 64 bits. In C the size of int, unsigned int, long, long long int, unsigned long long int, etc are not fixed, the change according to the CPU. sizeof(int) <= sizeof(long) <= sizeof(long long).

It's *recommended* that ints be the size of a standard register. So, those sizes do not have to follow the CPU architecture, and compilers could potentially use different sizes even on the same platform. D (and most languages that came after C) did a much better job on this. BTW, I think long long is a gnu extension, it's not standard C (I don't think long long exists in Visual C for instance). -Steve
Feb 25 2011
parent reply Bekenn <leaveme alone.com> writes:
On 2/25/2011 7:24 PM, Steven Schveighoffer wrote:
 BTW, I think long long is a gnu extension, it's not standard C (I don't
 think long long exists in Visual C for instance).

I'm pretty sure it's standard as of C99 (though not yet for C++; that's coming with C++0x). MSVC does indeed support it.
Feb 26 2011
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday 27 February 2011 05:41:49 Steven Schveighoffer wrote:
 On Sat, 26 Feb 2011 22:24:52 -0500, Bekenn <leaveme alone.com> wrote:
 On 2/25/2011 7:24 PM, Steven Schveighoffer wrote:
 BTW, I think long long is a gnu extension, it's not standard C (I don't
 think long long exists in Visual C for instance).

I'm pretty sure it's standard as of C99 (though not yet for C++; that's coming with C++0x). MSVC does indeed support it.

OK, I was not aware, my C book is from college, and I went to college in 94. I always thought in Windows you had to use something like __int64.

That would be the smart thing to do, but long long does exist. IHMO, if you don't care about the size of an integral type in C/C++, you use int. Otherwise, you use a type that specifices it's size and is _guaranteed_ to be that size on all systems. Using types like long and long long is just asking for it. Fortunately, D specifies the size of its types, so that isn't a problem. - Jonathan M Davis
Feb 27 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sat, 26 Feb 2011 22:24:52 -0500, Bekenn <leaveme alone.com> wrote:

 On 2/25/2011 7:24 PM, Steven Schveighoffer wrote:
 BTW, I think long long is a gnu extension, it's not standard C (I don't
 think long long exists in Visual C for instance).

I'm pretty sure it's standard as of C99 (though not yet for C++; that's coming with C++0x). MSVC does indeed support it.

OK, I was not aware, my C book is from college, and I went to college in 94. I always thought in Windows you had to use something like __int64. -Steve
Feb 27 2011
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-02-26 01:28, simendsjo wrote:
 C is not my strong side, so I'm having some problems wrapping some code.

 I found a couple of sources on this:
 1) http://www.digitalmars.com/d/2.0/htomodule.html
 2) http://www.digitalmars.com/d/2.0/interfaceToC.html

 1)
 C's long is the same as D's int.
 long long is long

 2)
 C 32bit's long long is D's long, C 64 bits long is D's long.

 So.. A long in C is the same as the platform size? And long long doesn't
 exist in 64 bit?

In general you can follow the table at http://www.digitalmars.com/d/2.0/htomodule.html But when it comes to "long" in C you have to be careful. On 32bit platforms a C "long" will be 32bit long. But on 64bit platforms it depends of what data model is used. To simplify things: * On Windows 64bit a C "long" will be 32bit long * On Posix 64bit a C "long" will be 64bit long. What you can do is to create an alias called "c_long" and "c_ulong", something like this: version (D_LP64) { version (Windows) { alias int c_long; alias uint c_ulong; } else { alias long c_long; alias ulong c_ulong; } } else { alias int c_long; alias uint c_ulong; } To read more about data models: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models -- /Jacob Carlborg
Feb 26 2011
parent reply Mike Wey <mike-wey example.com> writes:
On 02/26/2011 11:49 AM, Jacob Carlborg wrote:
 On 2011-02-26 01:28, simendsjo wrote:
 C is not my strong side, so I'm having some problems wrapping some code.

 I found a couple of sources on this:
 1) http://www.digitalmars.com/d/2.0/htomodule.html
 2) http://www.digitalmars.com/d/2.0/interfaceToC.html

 1)
 C's long is the same as D's int.
 long long is long

 2)
 C 32bit's long long is D's long, C 64 bits long is D's long.

 So.. A long in C is the same as the platform size? And long long doesn't
 exist in 64 bit?

In general you can follow the table at http://www.digitalmars.com/d/2.0/htomodule.html But when it comes to "long" in C you have to be careful. On 32bit platforms a C "long" will be 32bit long. But on 64bit platforms it depends of what data model is used. To simplify things: * On Windows 64bit a C "long" will be 32bit long * On Posix 64bit a C "long" will be 64bit long. What you can do is to create an alias called "c_long" and "c_ulong", something like this: version (D_LP64) { version (Windows) { alias int c_long; alias uint c_ulong; } else { alias long c_long; alias ulong c_ulong; } } else { alias int c_long; alias uint c_ulong; } To read more about data models: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

You can also import core.stdc.config witch defines both c_long and c_ulong. -- Mike Wey
Feb 26 2011
next sibling parent reply simendsjo <simen.endsjo pandavre.com> writes:
On 26.02.2011 17:06, Mike Wey wrote:
 On 02/26/2011 11:49 AM, Jacob Carlborg wrote:
 On 2011-02-26 01:28, simendsjo wrote:
 C is not my strong side, so I'm having some problems wrapping some code.

 I found a couple of sources on this:
 1) http://www.digitalmars.com/d/2.0/htomodule.html
 2) http://www.digitalmars.com/d/2.0/interfaceToC.html

 1)
 C's long is the same as D's int.
 long long is long

 2)
 C 32bit's long long is D's long, C 64 bits long is D's long.

 So.. A long in C is the same as the platform size? And long long doesn't
 exist in 64 bit?

In general you can follow the table at http://www.digitalmars.com/d/2.0/htomodule.html But when it comes to "long" in C you have to be careful. On 32bit platforms a C "long" will be 32bit long. But on 64bit platforms it depends of what data model is used. To simplify things: * On Windows 64bit a C "long" will be 32bit long * On Posix 64bit a C "long" will be 64bit long. What you can do is to create an alias called "c_long" and "c_ulong", something like this: version (D_LP64) { version (Windows) { alias int c_long; alias uint c_ulong; } else { alias long c_long; alias ulong c_ulong; } } else { alias int c_long; alias uint c_ulong; } To read more about data models: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

You can also import core.stdc.config witch defines both c_long and c_ulong.

version(X86_64) { version(Windows) { version = LLP64; } else version(Posix) { version = LP64; } else { static assert(0); } version(LLP64) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias int c_long; alias uint c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(LP64) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(ILP64) { alias short c_short; alias ushort c_ushort; alias long c_int; alias ulong c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(SILP64) { alias long c_short; alias ulong c_ushort; alias long c_int; alias ulong c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else { static assert(0); } } else version(X86) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias int c_long; alias uint c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias uint c_size_t; } else { static assert(0); }
Feb 26 2011
next sibling parent reply Mike Wey <mike-wey example.com> writes:
On 02/26/2011 05:58 PM, simendsjo wrote:
 On 26.02.2011 17:06, Mike Wey wrote:
 On 02/26/2011 11:49 AM, Jacob Carlborg wrote:
 On 2011-02-26 01:28, simendsjo wrote:
 C is not my strong side, so I'm having some problems wrapping some
 code.

 I found a couple of sources on this:
 1) http://www.digitalmars.com/d/2.0/htomodule.html
 2) http://www.digitalmars.com/d/2.0/interfaceToC.html

 1)
 C's long is the same as D's int.
 long long is long

 2)
 C 32bit's long long is D's long, C 64 bits long is D's long.

 So.. A long in C is the same as the platform size? And long long
 doesn't
 exist in 64 bit?

In general you can follow the table at http://www.digitalmars.com/d/2.0/htomodule.html But when it comes to "long" in C you have to be careful. On 32bit platforms a C "long" will be 32bit long. But on 64bit platforms it depends of what data model is used. To simplify things: * On Windows 64bit a C "long" will be 32bit long * On Posix 64bit a C "long" will be 64bit long. What you can do is to create an alias called "c_long" and "c_ulong", something like this: version (D_LP64) { version (Windows) { alias int c_long; alias uint c_ulong; } else { alias long c_long; alias ulong c_ulong; } } else { alias int c_long; alias uint c_ulong; } To read more about data models: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

You can also import core.stdc.config witch defines both c_long and c_ulong.

version(X86_64) { version(Windows) { version = LLP64; } else version(Posix) { version = LP64; } else { static assert(0); } version(LLP64) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias int c_long; alias uint c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(LP64) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(ILP64) { alias short c_short; alias ushort c_ushort; alias long c_int; alias ulong c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(SILP64) { alias long c_short; alias ulong c_ushort; alias long c_int; alias ulong c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else { static assert(0); } } else version(X86) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias int c_long; alias uint c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias uint c_size_t; } else { static assert(0); }

The aliases look correct, but i don't think you'll need ILP64 or SILP64 any time soon. -- Mike Wey
Feb 26 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-02-26 23:02, Mike Wey wrote:
 On 02/26/2011 05:58 PM, simendsjo wrote:
 On 26.02.2011 17:06, Mike Wey wrote:
 On 02/26/2011 11:49 AM, Jacob Carlborg wrote:
 On 2011-02-26 01:28, simendsjo wrote:
 C is not my strong side, so I'm having some problems wrapping some
 code.

 I found a couple of sources on this:
 1) http://www.digitalmars.com/d/2.0/htomodule.html
 2) http://www.digitalmars.com/d/2.0/interfaceToC.html

 1)
 C's long is the same as D's int.
 long long is long

 2)
 C 32bit's long long is D's long, C 64 bits long is D's long.

 So.. A long in C is the same as the platform size? And long long
 doesn't
 exist in 64 bit?

In general you can follow the table at http://www.digitalmars.com/d/2.0/htomodule.html But when it comes to "long" in C you have to be careful. On 32bit platforms a C "long" will be 32bit long. But on 64bit platforms it depends of what data model is used. To simplify things: * On Windows 64bit a C "long" will be 32bit long * On Posix 64bit a C "long" will be 64bit long. What you can do is to create an alias called "c_long" and "c_ulong", something like this: version (D_LP64) { version (Windows) { alias int c_long; alias uint c_ulong; } else { alias long c_long; alias ulong c_ulong; } } else { alias int c_long; alias uint c_ulong; } To read more about data models: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

You can also import core.stdc.config witch defines both c_long and c_ulong.

version(X86_64) { version(Windows) { version = LLP64; } else version(Posix) { version = LP64; } else { static assert(0); } version(LLP64) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias int c_long; alias uint c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(LP64) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(ILP64) { alias short c_short; alias ushort c_ushort; alias long c_int; alias ulong c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(SILP64) { alias long c_short; alias ulong c_ushort; alias long c_int; alias ulong c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else { static assert(0); } } else version(X86) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias int c_long; alias uint c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias uint c_size_t; } else { static assert(0); }

The aliases look correct, but i don't think you'll need ILP64 or SILP64 any time soon.

I agree. -- /Jacob Carlborg
Feb 27 2011
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-02-26 17:58, simendsjo wrote:
 On 26.02.2011 17:06, Mike Wey wrote:
 On 02/26/2011 11:49 AM, Jacob Carlborg wrote:
 On 2011-02-26 01:28, simendsjo wrote:
 C is not my strong side, so I'm having some problems wrapping some
 code.

 I found a couple of sources on this:
 1) http://www.digitalmars.com/d/2.0/htomodule.html
 2) http://www.digitalmars.com/d/2.0/interfaceToC.html

 1)
 C's long is the same as D's int.
 long long is long

 2)
 C 32bit's long long is D's long, C 64 bits long is D's long.

 So.. A long in C is the same as the platform size? And long long
 doesn't
 exist in 64 bit?

In general you can follow the table at http://www.digitalmars.com/d/2.0/htomodule.html But when it comes to "long" in C you have to be careful. On 32bit platforms a C "long" will be 32bit long. But on 64bit platforms it depends of what data model is used. To simplify things: * On Windows 64bit a C "long" will be 32bit long * On Posix 64bit a C "long" will be 64bit long. What you can do is to create an alias called "c_long" and "c_ulong", something like this: version (D_LP64) { version (Windows) { alias int c_long; alias uint c_ulong; } else { alias long c_long; alias ulong c_ulong; } } else { alias int c_long; alias uint c_ulong; } To read more about data models: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

You can also import core.stdc.config witch defines both c_long and c_ulong.

version(X86_64) { version(Windows) { version = LLP64; } else version(Posix) { version = LP64; } else { static assert(0); } version(LLP64) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias int c_long; alias uint c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(LP64) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(ILP64) { alias short c_short; alias ushort c_ushort; alias long c_int; alias ulong c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(SILP64) { alias long c_short; alias ulong c_ushort; alias long c_int; alias ulong c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else { static assert(0); } } else version(X86) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias int c_long; alias uint c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias uint c_size_t; } else { static assert(0); }

I suggest you use core.stdc.config instead, I forgot it existed. BTW size_t already exists in D (defined in the object module) and it will be the same as size_t in C. -- /Jacob Carlborg
Feb 27 2011
parent simendsjo <simen.endsjo pandavre.com> writes:
On 27.02.2011 11:43, Jacob Carlborg wrote:
 On 2011-02-26 17:58, simendsjo wrote:
 On 26.02.2011 17:06, Mike Wey wrote:
 On 02/26/2011 11:49 AM, Jacob Carlborg wrote:
 On 2011-02-26 01:28, simendsjo wrote:
 C is not my strong side, so I'm having some problems wrapping some
 code.

 I found a couple of sources on this:
 1) http://www.digitalmars.com/d/2.0/htomodule.html
 2) http://www.digitalmars.com/d/2.0/interfaceToC.html

 1)
 C's long is the same as D's int.
 long long is long

 2)
 C 32bit's long long is D's long, C 64 bits long is D's long.

 So.. A long in C is the same as the platform size? And long long
 doesn't
 exist in 64 bit?

In general you can follow the table at http://www.digitalmars.com/d/2.0/htomodule.html But when it comes to "long" in C you have to be careful. On 32bit platforms a C "long" will be 32bit long. But on 64bit platforms it depends of what data model is used. To simplify things: * On Windows 64bit a C "long" will be 32bit long * On Posix 64bit a C "long" will be 64bit long. What you can do is to create an alias called "c_long" and "c_ulong", something like this: version (D_LP64) { version (Windows) { alias int c_long; alias uint c_ulong; } else { alias long c_long; alias ulong c_ulong; } } else { alias int c_long; alias uint c_ulong; } To read more about data models: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

You can also import core.stdc.config witch defines both c_long and c_ulong.

version(X86_64) { version(Windows) { version = LLP64; } else version(Posix) { version = LP64; } else { static assert(0); } version(LLP64) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias int c_long; alias uint c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(LP64) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(ILP64) { alias short c_short; alias ushort c_ushort; alias long c_int; alias ulong c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else version(SILP64) { alias long c_short; alias ulong c_ushort; alias long c_int; alias ulong c_uint; alias long c_long; alias ulong c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias ulong c_size_t; } else { static assert(0); } } else version(X86) { alias short c_short; alias ushort c_ushort; alias int c_int; alias uint c_uint; alias int c_long; alias uint c_ulong; alias long c_longlong; alias ulong c_ulonglong; alias uint c_size_t; } else { static assert(0); }

I suggest you use core.stdc.config instead, I forgot it existed. BTW size_t already exists in D (defined in the object module) and it will be the same as size_t in C.

Ok. Thanks.
Feb 27 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-02-26 17:06, Mike Wey wrote:
 On 02/26/2011 11:49 AM, Jacob Carlborg wrote:
 On 2011-02-26 01:28, simendsjo wrote:
 C is not my strong side, so I'm having some problems wrapping some code.

 I found a couple of sources on this:
 1) http://www.digitalmars.com/d/2.0/htomodule.html
 2) http://www.digitalmars.com/d/2.0/interfaceToC.html

 1)
 C's long is the same as D's int.
 long long is long

 2)
 C 32bit's long long is D's long, C 64 bits long is D's long.

 So.. A long in C is the same as the platform size? And long long doesn't
 exist in 64 bit?

In general you can follow the table at http://www.digitalmars.com/d/2.0/htomodule.html But when it comes to "long" in C you have to be careful. On 32bit platforms a C "long" will be 32bit long. But on 64bit platforms it depends of what data model is used. To simplify things: * On Windows 64bit a C "long" will be 32bit long * On Posix 64bit a C "long" will be 64bit long. What you can do is to create an alias called "c_long" and "c_ulong", something like this: version (D_LP64) { version (Windows) { alias int c_long; alias uint c_ulong; } else { alias long c_long; alias ulong c_ulong; } } else { alias int c_long; alias uint c_ulong; } To read more about data models: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

You can also import core.stdc.config witch defines both c_long and c_ulong.

Yeah, I always forgets that module in druntime, even though it's based on Tango where I do remember it. -- /Jacob Carlborg
Feb 27 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday 26 February 2011 02:51:08 Jacob Carlborg wrote:
 On 2011-02-26 02:35, Jonathan M Davis wrote:
 On Friday, February 25, 2011 17:16:31 simendsjo wrote:
 On 26.02.2011 02:06, bearophile wrote:
 simendsjo:
 So.. A long in C is the same as the platform size? And long long
 doesn't exist in 64 bit?

In D the size of int/uint is 32 bits and long/ulong is 64 bits. In C the size of int, unsigned int, long, long long int, unsigned long long int, etc are not fixed, the change according to the CPU. sizeof(int)<= sizeof(long)<= sizeof(long long). A help: http://www.digitalmars.com/d/2.0/phobos/std_stdint.html Bye, bearophile

Ouch.. Any tips on porting C code that would work nicely with a transition to 64 bit? Should I change all long and int to int_atleast_32_t and long long to 64?

It depends entirely on what the code is doing. It could be completely safe to convert all ints, longs, and long longs to long to long. Or you may have to choose int or long depending on what system the code is supposed to be for. In many cases, using a larger type wouldn't matter, since it can hold more than the smaller type, so whether the type in C/C++ was 32 bits or 64 bits is irrelevant. In other cases, the type needs to be an exact size, because the code is doing bit shifts or whatnot (in which case they _should_ have been using int32_t and int64_t on Linux and whatever the equivalent is on Windows, but unfortunately, many programmers don't). And if you're dealing with a struct, it's possible that that struct has to be an exact size (e.g. for some binary format), and using the wrong type in converting could make it the wrong size. If you want to know what the appropriate D type is for the C/C++ code, you _need_ to know what it does. Now, IIRC, int is almost guaranteed to be 32 bits at this point, and long long is essentially guaranteed to be 64 bits, but long varies from system to system - both in terms of OS and architecture. IIRC, long is 32 bits on Solaris and Windows - both on x86 and x86_64 - but it's 32 bits in x86 Linux and 64 bits in x86_64 Linux. So, if all the code uses is int and long long, then it's probably reasonably safe to use int for int and long for long long, but it's ultimately system dependent. Personally, I would argue that C/C++ code should use int when you don't care about the size of an integral type and use the intX_t types (where X is 8, 16, 32, or 64) when you _do_ care about the size, but there's no guarantee that programmers are going to be that disciplined about it.

A C "long" is 64bit long on Solaris 64bit according to this: http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models

Well, I've run into problems before due the size of long differing on Linux and Solaris and I thought that it was 64-bit Linux and 64-bit Solaris, but maybe it was actually 32-bit Solaris (I _know_ that it was 64-bit Linux though). Regardless, it just goes to show how careful you have to be when dealing with long in C and C++. - Jonathan M Davis
Feb 26 2011