www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why is it that no one writes with portability in mind in druntime?

reply "Iain Buclaw" <ibuclaw ubuntu.com> writes:
https://github.com/D-Programming-Language/druntime/pull/663
Nov 24 2013
next sibling parent reply Shammah Chancellor <anonymous coward.com> writes:
On 2013-11-24 11:38:25 +0000, Iain Buclaw said:

 https://github.com/D-Programming-Language/druntime/pull/663
A link to pages of a pull extension for CTFE hashes. Care to clarify?
Nov 24 2013
next sibling parent reply Johannes Pfau <nospam example.com> writes:
Am Sun, 24 Nov 2013 10:34:36 -0500
schrieb Shammah Chancellor <anonymous coward.com>:

 On 2013-11-24 11:38:25 +0000, Iain Buclaw said:
 
 https://github.com/D-Programming-Language/druntime/pull/663
A link to pages of a pull extension for CTFE hashes. Care to clarify?
A guess: Everything using floating point is probably assuming real is 80 bit. This and floating point unit tests always show up as the main problems when porting druntime / phobos. We have one type in D which has a different size depending on platform and it's the number one source for platform-specific problems... https://github.com/D-Programming-Language/druntime/pull/663/files#diff-d07f1a3835b1d391 103490da285999dR183
Nov 24 2013
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 11/24/13, Johannes Pfau <nospam example.com> wrote:
 We have one type in D which has a different size depending on platform
 and it's the number one source for platform-specific problems...
It seems any time a language defines something as implementation-specific or platform-specific it ends up giving everyone headaches. I don't know why D chose to use reals like that, after enforcing the sizes of long/int/etc. types.
Nov 24 2013
next sibling parent reply Shammah Chancellor <anonymous coward.com> writes:
On 2013-11-24 17:47:49 +0000, Andrej Mitrovic said:

 On 11/24/13, Johannes Pfau <nospam example.com> wrote:
 We have one type in D which has a different size depending on platform
 and it's the number one source for platform-specific problems...
It seems any time a language defines something as implementation-specific or platform-specific it ends up giving everyone headaches. I don't know why D chose to use reals like that, after enforcing the sizes of long/int/etc. types.
Having 80-bit reals on platforms that support them are helpful for numerical simulations. There use to be an article about this decision. However, phobos should never use real for this reason. It should only be used by application developers. Maybe a compiler flag to error when compiling code that includes real to make sure portable libraries don't use it? -Shammah
Nov 24 2013
parent "Joseph Rushton Wakeling" <joseph.wakeling webdrake.net> writes:
On Sunday, 24 November 2013 at 17:50:20 UTC, Shammah Chancellor 
wrote:
 Having 80-bit reals on platforms that support them are helpful 
 for numerical simulations.  There use to be an article about 
 this decision. However, phobos should never use real for this 
 reason.
What, so mathematical functions shouldn't use the highest-precision floating point?
Nov 24 2013
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/24/2013 9:47 AM, Andrej Mitrovic wrote:
 I don't know why D chose to use reals like that,
Because more precision is better.
Nov 24 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, November 24, 2013 18:47:49 Andrej Mitrovic wrote:
 On 11/24/13, Johannes Pfau <nospam example.com> wrote:
 We have one type in D which has a different size depending on platform
 and it's the number one source for platform-specific problems...
It seems any time a language defines something as implementation-specific or platform-specific it ends up giving everyone headaches. I don't know why D chose to use reals like that, after enforcing the sizes of long/int/etc. types.
I'd expect it's because D is a systems language and tries to give you full access to the hardware when you need it, and high-precision floating point types were considered useful enough that they shouldn't require inline assembly to work. However, in most cases, I think that what it means is that if you use reals where you care at all about the bit layout, you're just not going to be able to write platform-independent code (e.g. std.bitmanip punts or reals for swapping endianness). - Jonathan M Davis
Nov 24 2013
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, November 24, 2013 17:15:25 Johannes Pfau wrote:
 We have one type in D which has a different size depending on platform
 and it's the number one source for platform-specific problems...
No. We have several types which vary in size. In addition to real, there's also size_t (which should be being used in almost all D programs, whereas real is used in far fewer), and there's also ptrdiff_t, which is effectively an unsigned size_t. And of course, all of the pointer types vary in size, as do the c_* types from druntime when you have to interact with C (though those aren't part of the language - or even just treated as part of the language as size_t and ptrdiff_t are, since they're defined in object_.d). So, even if almost all of D's numeric types don't vary in size, there are some that do. But it is true that a large portion of our platform-specific problems stem from types that vary in size. - Jonathan M Davis
Nov 24 2013
next sibling parent reply "ponce" <crapmail spamfrommars.fr> writes:
On Sunday, 24 November 2013 at 22:38:15 UTC, Jonathan M Davis 
wrote:
 No. We have several types which vary in size. In addition to 
 real, there's
 also size_t (which should be being used in almost all D 
 programs, whereas real
 there's also ptrdiff_t, which is effectively an unsigned size_t.
Just to correct things, size_t is unsigned, ptrdiff_t is the signed one.
Nov 24 2013
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, November 25, 2013 00:34:31 ponce wrote:
 On Sunday, 24 November 2013 at 22:38:15 UTC, Jonathan M Davis
 
 wrote:
 No. We have several types which vary in size. In addition to
 real, there's
 also size_t (which should be being used in almost all D
 programs, whereas real
 there's also ptrdiff_t, which is effectively an unsigned size_t.
Just to correct things, size_t is unsigned, ptrdiff_t is the signed one.
Correct. I mistyped. Sorry about that. - Jonathan M Davis
Nov 24 2013
prev sibling next sibling parent reply "Craig Dillabaugh" <craig.dillabaugh gmail.com> writes:
On Sunday, 24 November 2013 at 22:38:15 UTC, Jonathan M Davis 
wrote:
 On Sunday, November 24, 2013 17:15:25 Johannes Pfau wrote:
 We have one type in D which has a different size depending on 
 platform
 and it's the number one source for platform-specific 
 problems...
No. We have several types which vary in size. In addition to real, there's also size_t (which should be being used in almost all D programs, whereas real is used in far fewer), and there's also ptrdiff_t, which is effectively an unsigned size_t. And of course, all of the pointer types vary in size, as do the c_* types from druntime when you have to interact with C (though those aren't part of the language - or even just treated as part of the language as size_t and ptrdiff_t are, since they're defined in object_.d). So, even if almost all of D's numeric types don't vary in size, there are some that do.
Isn't size_t unsigned and ptrdiff_t signed?
 But it is true that a large portion of our platform-specific 
 problems stem from
 types that vary in size.

 - Jonathan M Davis
Nov 24 2013
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, November 25, 2013 01:50:47 Craig Dillabaugh wrote:
 Isn't size_t unsigned and ptrdiff_t signed?
Yes. I mistyped. - Jonathan M Davis
Nov 24 2013
prev sibling parent reply "Iain Buclaw" <ibuclaw ubuntu.com> writes:
On Sunday, 24 November 2013 at 22:38:15 UTC, Jonathan M Davis 
wrote:
 But it is true that a large portion of our platform-specific 
 problems stem from
 types that vary in size.
Size *and* format. ie: big/little endian, 80/96/128bit reals, etc... My biggest problem with stuff like this (see link in original post) is that after so much combined effort getting things working across multiple architectures - just take a look at any pull for version MIPS, PPC, PPC64, SPARC, ARM, etc... or my pull for implementing std.math for almost all (double-double reals the main one missing), IEEE real types - someone goes ahead and breaks support for all these targets and no one thinks or lifts an eyebrow over it. Library maintainers need to stop writing code with the assumption that their code is only going to be used with dmd and x86, and they should have stopped doing it 6 months ago.
Nov 24 2013
next sibling parent "Iain Buclaw" <ibuclaw ubuntu.com> writes:
On Monday, 25 November 2013 at 07:43:38 UTC, Iain Buclaw wrote:
 Library maintainers need to stop writing code with the 
 assumption that their code is only going to be used with dmd 
 and x86, and they should have stopped doing it 6 months ago.
Aiming 'library maintainers' at the druntime/phobos folk. Because third party libraries are not a concern yet. ;)
Nov 24 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, November 25, 2013 08:43:37 Iain Buclaw wrote:
 On Sunday, 24 November 2013 at 22:38:15 UTC, Jonathan M Davis
 
 wrote:
 But it is true that a large portion of our platform-specific
 problems stem from
 types that vary in size.
Size *and* format. ie: big/little endian, 80/96/128bit reals, etc... My biggest problem with stuff like this (see link in original post) is that after so much combined effort getting things working across multiple architectures - just take a look at any pull for version MIPS, PPC, PPC64, SPARC, ARM, etc... or my pull for implementing std.math for almost all (double-double reals the main one missing), IEEE real types - someone goes ahead and breaks support for all these targets and no one thinks or lifts an eyebrow over it. Library maintainers need to stop writing code with the assumption that their code is only going to be used with dmd and x86, and they should have stopped doing it 6 months ago.
In a lot of cases, I expect that folks just forget. In others, they don't realize that what they're doing won't work on other targets. I'm aware of some of the issues involved with all of that, but I fully expect that I'm not aware of them all, and I expect that it's the same with many of the other developers. And since the autotester only targets dmd and x86(_64), non- x86(_64) breakage isn't caught when it occurs - though it's my understanding at this point, that the integration between gdc or ldc and the front-end is not smooth enough to be able to simply rebuild them when the front-end gets updated, which would likely be required to integrate them into the autotester. I don't know how to solve the main issue other than educating people better. Personally, I don't get involved with druntime pulls all that often, because I often don't feel qualified to do so (and I should get involved with Phobos pulls more than I do, but I'm busy enough these days that that's hard - though hopefully that will be improving relatively soon). I expect that there's enough work to get there that it'll be a while before we do, but if we could reach the point where gdc and ldc could be built as part of the autotester (especially if that can be done with multiple architectures), that would go a long way towards fixing the breakage problems. - Jonathan M Davis
Nov 25 2013
prev sibling next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 25/11/13 09:00, Jonathan M Davis wrote:
 I don't know how to solve the main issue other than educating people better.
Is it possible to define an artificial test situation where real is defined to be 64-bit, even though it's technically being compiled on x86(_64) hardware which supports 80-bit floats? That ought to catch any cases where someone assumes that real is 80-bit, no?
Nov 25 2013
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/24/13 11:43 PM, Iain Buclaw wrote:
 Library maintainers need to stop writing code with the assumption that
 their code is only going to be used with dmd and x86, and they should
 have stopped doing it 6 months ago.
I agree, but the real solution to that would be unittests that fail. Andrei
Nov 25 2013
parent Johannes Pfau <nospam example.com> writes:
Am Mon, 25 Nov 2013 09:46:14 -0800
schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 On 11/24/13 11:43 PM, Iain Buclaw wrote:
 Library maintainers need to stop writing code with the assumption
 that their code is only going to be used with dmd and x86, and they
 should have stopped doing it 6 months ago.
I agree, but the real solution to that would be unittests that fail. Andrei
Or static asserts. It looks like some people just don't know that the D real type is platform specific. A simple static if (real.mant_dig == 64) else static assert(false); Already helps a lot. If the code instead just assumes x86 real layout we usually only see memory corruption or bogus / invalid results and debugging that is not much fun.
Nov 25 2013
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 11/24/2013 11:43 PM, Iain Buclaw wrote:
 My biggest problem with stuff like this (see link in original post) is that
 after so much combined effort getting things working across multiple
 architectures - just take a look at any pull for version MIPS, PPC, PPC64,
 SPARC, ARM, etc... or my pull for implementing std.math for almost all
 (double-double reals the main one missing), IEEE real types - someone goes
ahead
 and breaks support for all these targets and no one thinks or lifts an eyebrow
 over it.
My experience with porting code across architectures is that if one personally has not done it before, one always gets it wrong, despite the best intentions. There's no substitute for a review of such pull requests by someone who has been there done that before. Saying people should be better educated about this simply will not work.
Nov 25 2013
prev sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 24/11/13 23:38, Jonathan M Davis wrote:
 No. We have several types which vary in size. In addition to real, there's
 also size_t (which should be being used in almost all D programs, whereas real
 is used in far fewer), and there's also ptrdiff_t, which is effectively an
 unsigned size_t. And of course, all of the pointer types vary in size, as do
 the c_* types from druntime when you have to interact with C (though those
 aren't part of the language - or even just treated as part of the language as
 size_t and ptrdiff_t are, since they're defined in object_.d). So, even if
 almost all of D's numeric types don't vary in size, there are some that do.
But ... am I not right that size_t and ptrdiff_t are essentially just defined as aliases to either ulong and long (for 64-bit) or uint and int (32-bit) code? So don't you essentially get support for them "for free" just by supporting 32- and 64-bit integral types? Or are there still problems that arise?
Nov 25 2013
prev sibling parent "Iain Buclaw" <ibuclaw ubuntu.com> writes:
On Sunday, 24 November 2013 at 15:34:37 UTC, Shammah Chancellor 
wrote:
 On 2013-11-24 11:38:25 +0000, Iain Buclaw said:

 https://github.com/D-Programming-Language/druntime/pull/663
A link to pages of a pull extension for CTFE hashes. Care to clarify?
You only need to look as far as the FloatTraits template to then shake your head in misery. ;-)
Nov 24 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, November 25, 2013 09:25:46 Joseph Rushton Wakeling wrote:
 On 24/11/13 23:38, Jonathan M Davis wrote:
 No. We have several types which vary in size. In addition to real, there's
 also size_t (which should be being used in almost all D programs, whereas
 real is used in far fewer), and there's also ptrdiff_t, which is
 effectively an unsigned size_t. And of course, all of the pointer types
 vary in size, as do the c_* types from druntime when you have to interact
 with C (though those aren't part of the language - or even just treated
 as part of the language as size_t and ptrdiff_t are, since they're
 defined in object_.d). So, even if almost all of D's numeric types don't
 vary in size, there are some that do.
But ... am I not right that size_t and ptrdiff_t are essentially just defined as aliases to either ulong and long (for 64-bit) or uint and int (32-bit) code? So don't you essentially get support for them "for free" just by supporting 32- and 64-bit integral types? Or are there still problems that arise?
Yes, they're aliases, but you have to worry about them. Take this code for instance. int len = arr.length; That code will compile as 32-bit, but it will _not_ compile as 64-bit, because length is size_t, which on 32-bit systems happens to be uint, which implicitly converts to int, whereas on 64-bit systems, it's ulong, which does _not_ implicitly convert to it. If you want to write D code that compiles on both 32-bit and 64-bit systems, you need to be cognizant of size_t and use it rather than int, uint, long, ulong, or any of the other integral types when the types involved are actually supposed to be size_t or ptrdiff_t. This is actually the type difference that's probably the _most_ likely to bite your average D programmer, not real, since at this point, most D programs won't ever be compiled on anything other than x86(_64), but many of them _will_ be compiled as both 32-bit and 64-bit depending on who compiles them and where they compile them. As we do more with ARM and other platforms, issues with real and possibly othe system-specific stuff will become more prevalent, but at the moment, they're mostly future problems rather than current ones. The major exception is druntime and Phobos (especially druntime) as work is currently being done to make those work on other platforms, and work is currently being done on gdc and ldc to support those other platforms in the compiler. - Jonathan M Davis
Nov 25 2013
prev sibling next sibling parent reply Brad Roberts <braddr puremagic.com> writes:
On 11/24/13 3:38 AM, Iain Buclaw wrote:
 https://github.com/D-Programming-Language/druntime/pull/663
There's only one effective way to keep things portable, and that's continuous testing on multiple platforms that exercise the various differences. The only way to get that is to have druntime and phobos pulls continuously tested against dmd and gdc and ldc as a condition of merging. Relying on reviewers who have little to no experience maintaining those non-x86 platforms is doomed to failure. It doesn't surprise me in the least that non-x86-portability issues arise without being caught by the current committers and reviewers.
Nov 25 2013
parent reply "qznc" <qznc web.de> writes:
On Monday, 25 November 2013 at 09:05:14 UTC, Brad Roberts wrote:
 On 11/24/13 3:38 AM, Iain Buclaw wrote:
 https://github.com/D-Programming-Language/druntime/pull/663
There's only one effective way to keep things portable, and that's continuous testing on multiple platforms that exercise the various differences. The only way to get that is to have druntime and phobos pulls continuously tested against dmd and gdc and ldc as a condition of merging.
The gold standard: Every pull request (or every commit) should be tested with DMD/LDC/GDC on x86/amd64/arm with Linux/Win/OSX. That is already 27 variants. Actually there should probably be more like with/without SSE.
Nov 25 2013
next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 25/11/13 13:28, qznc wrote:
 The gold standard: Every pull request (or every commit) should be tested with
 DMD/LDC/GDC on x86/amd64/arm with Linux/Win/OSX. That is already 27 variants.
 Actually there should probably be more like with/without SSE.
You have a challenge that (AFAIK, as things are) patches to the frontend can't be automatically guaranteed to apply cleanly to GDC and LDC as well as DMD. And given that druntime and phobos patches can depend on frontend features, there's some difficulty in being able to automatically test patches to any part of the D core code against all the backends.
Nov 25 2013
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-11-25 13:28, qznc wrote:

 The gold standard: Every pull request (or every commit) should be tested
 with DMD/LDC/GDC on x86/amd64/arm with Linux/Win/OSX. That is already 27
 variants. Actually there should probably be more like with/without SSE.
And FreeBSD. -- /Jacob Carlborg
Nov 25 2013
prev sibling parent "nazriel" <spam dzfl.pl> writes:
On Monday, 25 November 2013 at 12:28:27 UTC, qznc wrote:
 On Monday, 25 November 2013 at 09:05:14 UTC, Brad Roberts wrote:
 On 11/24/13 3:38 AM, Iain Buclaw wrote:
 https://github.com/D-Programming-Language/druntime/pull/663
There's only one effective way to keep things portable, and that's continuous testing on multiple platforms that exercise the various differences. The only way to get that is to have druntime and phobos pulls continuously tested against dmd and gdc and ldc as a condition of merging.
The gold standard: Every pull request (or every commit) should be tested with DMD/LDC/GDC on x86/amd64/arm
And MIPS, PPC, PPC64, SPARC :))))
 with Linux/Win/OSX.
And FreeBSD
 That is already 27 variants. Actually there should probably be 
 more like with/without SSE.
Nov 25 2013
prev sibling next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 25/11/13 09:52, Jonathan M Davis wrote:
 Yes, they're aliases, but you have to worry about them. Take this code for
 instance.

 int len = arr.length;

 That code will compile as 32-bit, but it will _not_ compile as 64-bit, because
 length is size_t, which on 32-bit systems happens to be uint, which implicitly
 converts to int, whereas on 64-bit systems, it's ulong, which does _not_
 implicitly convert to it.
You're quite right -- I was just thinking about underlying stuff along the lines of what Iain was pointing out for real, not "user-land" cases like this. To be honest, I assumed that anyone with any experience or common sense would understand stuff like the example you've described, and not write such code. But that's probably very very naive ... :-) The size_t case I rather like to think of is: size_t m = ...; size_t p = 1 << m; // should this be 1U, 1UL ... ?
Nov 25 2013
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, November 25, 2013 10:40:11 Joseph Rushton Wakeling wrote:
 On 25/11/13 09:52, Jonathan M Davis wrote:
 Yes, they're aliases, but you have to worry about them. Take this code for
 instance.
 
 int len = arr.length;
 
 That code will compile as 32-bit, but it will _not_ compile as 64-bit,
 because length is size_t, which on 32-bit systems happens to be uint,
 which implicitly converts to int, whereas on 64-bit systems, it's ulong,
 which does _not_ implicitly convert to it.
You're quite right -- I was just thinking about underlying stuff along the lines of what Iain was pointing out for real, not "user-land" cases like this. To be honest, I assumed that anyone with any experience or common sense would understand stuff like the example you've described, and not write such code. But that's probably very very naive ... :-)
Many people seem to just use int everywhere, and a lot of D code failed to compile when 64-bit support was finally added. It's probably less a problem now then it used to be, but it's still not all that uncommon to see code examples that get it wrong (particularly from Windows users, where using 64-bit is more of a pain). It happens all the time in C/C++ as well, but C/C++ will allow the conversion implicitly, so for better or worse, it works as long as the numbers aren't too large.
 The size_t case I rather like to think of is:
 
       size_t m = ...;
       size_t p = 1 << m;    // should this be 1U, 1UL ... ?
I'd be _very_ suspicious of any bitshifts that aren't done on types with a fixed size. - Jonathan M Davis
Nov 25 2013
parent reply "froglegs" <nono yahoo.com> writes:
int len = arr.length;
That isn't an error in D? Every C++ code base I've worked in enables max warnings/warnings as errors, this would never compile-- Does it at least trigger a warning?
Nov 25 2013
next sibling parent "Gary Willoughby" <dev nomad.so> writes:
On Monday, 25 November 2013 at 11:15:00 UTC, froglegs wrote:
int len = arr.length;
That isn't an error in D? Every C++ code base I've worked in enables max warnings/warnings as errors, this would never compile-- Does it at least trigger a warning?
Because `arr.length` returns a `size_t` value i would imagine this compiles fine on a 32bit OS but throws an error on a 64bit OS. I think this demonstrates precisely the problem.
Nov 25 2013
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, November 25, 2013 12:14:59 froglegs wrote:
int len = arr.length;
That isn't an error in D? Every C++ code base I've worked in enables max warnings/warnings as errors, this would never compile-- Does it at least trigger a warning?
No. It's not a warning, and dmd is not big on warnings (and IMHO warnings you should be abolished, but that's another discussion). Regardless, given how size_t is implemented, the compiler doesn't really even know that it exists anyway. It's aliased to uint on 32-bit systems and ulong on 64-bit systems, so every place that size_t is used, it gets replaced with the type that it's aliased to, and the compiler forgets that it was ever anything else - the same thing happens with all aliases. So, on 32-bit systems, size_t is uint and int len = arr.length; works just fine, because uint implicitly converts to int. Whereas on 64-bit systems, size_t is ulong, and ulong does _not_ implicitly convert to int, so you get an error. So, on 32-bit systems, it compiles just fine, and 64-bit systems you get an error, but no systems will give you a warning. - Jonathan M Davis
Nov 25 2013
parent "froglegs" <nono yahoo.com> writes:
  I understand that it is converting a uint32 to a int32.  My 
point is that in C++ you can make this a warning, and then make 
all warnings errors. So this would not compile in any sane 
codebase since a int cannot express the full range of a uint. 
Perhaps D just better errors/warnings if it is unable to capture 
this...


On Monday, 25 November 2013 at 11:51:22 UTC, Jonathan M Davis 
wrote:
 On Monday, November 25, 2013 12:14:59 froglegs wrote:
int len = arr.length;
That isn't an error in D? Every C++ code base I've worked in enables max warnings/warnings as errors, this would never compile-- Does it at least trigger a warning?
No. It's not a warning, and dmd is not big on warnings (and IMHO warnings you should be abolished, but that's another discussion). Regardless, given how size_t is implemented, the compiler doesn't really even know that it exists anyway. It's aliased to uint on 32-bit systems and ulong on 64-bit systems, so every place that size_t is used, it gets replaced with the type that it's aliased to, and the compiler forgets that it was ever anything else - the same thing happens with all aliases. So, on 32-bit systems, size_t is uint and int len = arr.length; works just fine, because uint implicitly converts to int. Whereas on 64-bit systems, size_t is ulong, and ulong does _not_ implicitly convert to int, so you get an error. So, on 32-bit systems, it compiles just fine, and 64-bit systems you get an error, but no systems will give you a warning. - Jonathan M Davis
Nov 26 2013
prev sibling next sibling parent Joseph Rushton Wakeling <joseph.wakeling webdrake.net> writes:
On 25/11/13 11:34, Jonathan M Davis wrote:
 Many people seem to just use int everywhere, and a lot of D code failed to
 compile when 64-bit support was finally added.
Ack :-( One thing that slightly rings alarm bells for me with D is that, because the integral sizes are fixed, people use short/ushort, int/uint, long/ulong etc. for explicit 16-, 32- or 64-bit integrals. By contrast I do rather like the explicitness of something like uint64_t as a means of saying, "Yes, at this point in the code I really, really want a precisely 64-bit unsigned integral type." IIRC we do have them in D code, but isn't their use frowned on?
 The size_t case I rather like to think of is:

        size_t m = ...;
        size_t p = 1 << m;    // should this be 1U, 1UL ... ?
I'd be _very_ suspicious of any bitshifts that aren't done on types with a fixed size.
This was in fact exactly how I learned about how to handle 32- vs 64-bit issues. I had some simulation code suddenly start generating different values after I installed a 64-bit OS. My 32-bit code had run fine because the wraparound of the 1 << m bitshift brought it back around to where it was supposed to be (I was shifting it by about 30 or 31), whereas on 64-bit it was (surprise surprise) landing in the wrong place. I doubt that I can say that I've _never_ written unportable code since then, but ever since, I've always tried to address such size-related issues.
Nov 25 2013
prev sibling parent reply "IgorStepanov" <wazar mail.ru> writes:
On Sunday, 24 November 2013 at 11:38:27 UTC, Iain Buclaw wrote:
 https://github.com/D-Programming-Language/druntime/pull/663
This code is not portable only on CTFE part. (All those float manipulations run at compile time) I see three unportable aspects: 1. This code supports only 80bit real. What other formats we need to support? Can the compiler support operations on those (or more precise) formats? AFAIK dmd frontend perform all float operations in 80 bit real and supports only x86. 2. This code don't considers a float byte order. But compiler don't inform user code about float BO. There are LittleEndian/BigEndian versions for integers, but not for floats. You can add this versions on compiler and I'll fix this aspect in druntime code. 3. FloatTraits. Yes, thay works only with x86. Please, get link to other supported float formats and I'll extend FloatTraits to those formats. P.S. This PR expected pull during month. You could write you portability suggestion in the discussion. P.P.S. This is experemental CTFE float->ubyte[] code. It can be fixed later and don't break any existing code.
Nov 25 2013
parent reply Iain Buclaw <ibuclaw gdcproject.org> writes:
On 25 November 2013 21:44, IgorStepanov <wazar mail.ru> wrote:
 On Sunday, 24 November 2013 at 11:38:27 UTC, Iain Buclaw wrote:
 https://github.com/D-Programming-Language/druntime/pull/663
This code is not portable only on CTFE part. (All those float manipulations run at compile time) I see three unportable aspects: 1. This code supports only 80bit real. What other formats we need to support? Can the compiler support operations on those (or more precise) formats? AFAIK dmd frontend perform all float operations in 80 bit real and supports only x86.
The following IEEE 'real' formats are currently supported: 64 bit Big-endian 'double' (eg PowerPC) 128 bit Big-endian 'quadruple' (eg SPARC) 64 bit Little-endian 'double' (eg x86-SSE2) 80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium). 128 bit Little-endian 'quadruple' (not implemented on any known processor!) Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support At least support for these is a must: version(LittleEndian) { static assert(real.mant_dig == 53 || real.mant_dig==64 || real.mant_dig == 113); } else { static assert(real.mant_dig == 53 || real.mant_dig == 113); } 128 bit doubledouble formats (real.mant_dig == 106) - are a future goal.
 2. This code don't considers a float byte order. But compiler don't inform
 user code about float BO. There are LittleEndian/BigEndian versions for
 integers, but not for floats. You can add this versions on compiler and I'll
 fix this aspect in druntime code.
There doesn't exist a machine where the most significant byte of a word is ordered differently to floats. See std.math if in doubt, as this is already implemented.
 3. FloatTraits. Yes, thay works only with x86. Please, get link to other
 supported float formats and I'll extend FloatTraits to those formats.
See std.math, which already has a cross-platform implementation of that template with the same name (that amazingly existed years ago).
Nov 25 2013
parent reply "IgorStepanov" <wazar mail.ru> writes:
On Monday, 25 November 2013 at 22:54:03 UTC, Iain Buclaw wrote:
 On 25 November 2013 21:44, IgorStepanov <wazar mail.ru> wrote:
 On Sunday, 24 November 2013 at 11:38:27 UTC, Iain Buclaw wrote:
 https://github.com/D-Programming-Language/druntime/pull/663
This code is not portable only on CTFE part. (All those float manipulations run at compile time) I see three unportable aspects: 1. This code supports only 80bit real. What other formats we need to support? Can the compiler support operations on those (or more precise) formats? AFAIK dmd frontend perform all float operations in 80 bit real and supports only x86.
The following IEEE 'real' formats are currently supported: 64 bit Big-endian 'double' (eg PowerPC) 128 bit Big-endian 'quadruple' (eg SPARC) 64 bit Little-endian 'double' (eg x86-SSE2) 80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium). 128 bit Little-endian 'quadruple' (not implemented on any known processor!) Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support At least support for these is a must: version(LittleEndian) { static assert(real.mant_dig == 53 || real.mant_dig==64 || real.mant_dig == 113); } else { static assert(real.mant_dig == 53 || real.mant_dig == 113); } 128 bit doubledouble formats (real.mant_dig == 106) - are a future goal.
 2. This code don't considers a float byte order. But compiler 
 don't inform
 user code about float BO. There are LittleEndian/BigEndian 
 versions for
 integers, but not for floats. You can add this versions on 
 compiler and I'll
 fix this aspect in druntime code.
There doesn't exist a machine where the most significant byte of a word is ordered differently to floats. See std.math if in doubt, as this is already implemented.
 3. FloatTraits. Yes, thay works only with x86. Please, get 
 link to other
 supported float formats and I'll extend FloatTraits to those 
 formats.
See std.math, which already has a cross-platform implementation of that template with the same name (that amazingly existed years ago).
I can't implement CTFE support of types more precise than x86 80bit real. A think, all IEEE floats will be successfully processed like float and double (with same algorithm). But until CTFE don't support float with real.mant_dig>64 I can't process this types. Resume: I'll modify FloatTraits, consider endianess and add assert(0) for too precise types.
Nov 25 2013
parent Iain Buclaw <ibuclaw gdcproject.org> writes:
On 25 November 2013 23:36, IgorStepanov <wazar mail.ru> wrote:
 On Monday, 25 November 2013 at 22:54:03 UTC, Iain Buclaw wrote:
 On 25 November 2013 21:44, IgorStepanov <wazar mail.ru> wrote:
 On Sunday, 24 November 2013 at 11:38:27 UTC, Iain Buclaw wrote:
 https://github.com/D-Programming-Language/druntime/pull/663
This code is not portable only on CTFE part. (All those float manipulations run at compile time) I see three unportable aspects: 1. This code supports only 80bit real. What other formats we need to support? Can the compiler support operations on those (or more precise) formats? AFAIK dmd frontend perform all float operations in 80 bit real and supports only x86.
The following IEEE 'real' formats are currently supported: 64 bit Big-endian 'double' (eg PowerPC) 128 bit Big-endian 'quadruple' (eg SPARC) 64 bit Little-endian 'double' (eg x86-SSE2) 80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium). 128 bit Little-endian 'quadruple' (not implemented on any known processor!) Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support At least support for these is a must: version(LittleEndian) { static assert(real.mant_dig == 53 || real.mant_dig==64 || real.mant_dig == 113); } else { static assert(real.mant_dig == 53 || real.mant_dig == 113); } 128 bit doubledouble formats (real.mant_dig == 106) - are a future goal.
 2. This code don't considers a float byte order. But compiler don't
 inform
 user code about float BO. There are LittleEndian/BigEndian versions for
 integers, but not for floats. You can add this versions on compiler and
 I'll
 fix this aspect in druntime code.
There doesn't exist a machine where the most significant byte of a word is ordered differently to floats. See std.math if in doubt, as this is already implemented.
 3. FloatTraits. Yes, thay works only with x86. Please, get link to other
 supported float formats and I'll extend FloatTraits to those formats.
See std.math, which already has a cross-platform implementation of that template with the same name (that amazingly existed years ago).
I can't implement CTFE support of types more precise than x86 80bit real. A think, all IEEE floats will be successfully processed like float and double (with same algorithm). But until CTFE don't support float with real.mant_dig>64 I can't process this types. Resume: I'll modify FloatTraits, consider endianess and add assert(0) for too precise types.
Then test with a compiler that does have support in CTFE for floats with 128 bit precision then (actually, 160bit is the max stored :o)
Nov 25 2013