digitalmars.D - Why is it that no one writes with portability in mind in druntime?
- Iain Buclaw (1/1) Nov 24 2013 https://github.com/D-Programming-Language/druntime/pull/663
- Shammah Chancellor (2/3) Nov 24 2013 A link to pages of a pull extension for CTFE hashes. Care to clarify?
- Johannes Pfau (8/15) Nov 24 2013 A guess: Everything using floating point is probably assuming real is
- Andrej Mitrovic (5/7) Nov 24 2013 It seems any time a language defines something as
- Shammah Chancellor (8/16) Nov 24 2013 Having 80-bit reals on platforms that support them are helpful for
- Joseph Rushton Wakeling (4/8) Nov 24 2013 What, so mathematical functions shouldn't use the
- Walter Bright (2/3) Nov 24 2013 Because more precision is better.
- Jonathan M Davis (10/18) Nov 24 2013 I'd expect it's because D is a systems language and tries to give you fu...
- Jonathan M Davis (12/14) Nov 24 2013 No. We have several types which vary in size. In addition to real, there...
- ponce (4/9) Nov 24 2013 Just to correct things, size_t is unsigned, ptrdiff_t is the
- Jonathan M Davis (3/14) Nov 24 2013 Correct. I mistyped. Sorry about that.
- Craig Dillabaugh (3/28) Nov 24 2013 Isn't size_t unsigned and ptrdiff_t signed?
- Jonathan M Davis (3/4) Nov 24 2013 Yes. I mistyped.
- Iain Buclaw (15/18) Nov 24 2013 Size *and* format. ie: big/little endian, 80/96/128bit reals,
- Iain Buclaw (3/6) Nov 24 2013 Aiming 'library maintainers' at the druntime/phobos folk.
- Jonathan M Davis (20/42) Nov 25 2013 In a lot of cases, I expect that folks just forget. In others, they don...
- Joseph Rushton Wakeling (5/6) Nov 25 2013 Is it possible to define an artificial test situation where real is defi...
- Andrei Alexandrescu (3/6) Nov 25 2013 I agree, but the real solution to that would be unittests that fail.
- Johannes Pfau (9/19) Nov 25 2013 Or static asserts. It looks like some people just don't know that the D
- Walter Bright (6/13) Nov 25 2013 My experience with porting code across architectures is that if one pers...
- Joseph Rushton Wakeling (5/13) Nov 25 2013 But ... am I not right that size_t and ptrdiff_t are essentially just de...
- Iain Buclaw (5/9) Nov 24 2013 You only need to look as far as the FloatTraits template to then
- Jonathan M Davis (23/38) Nov 25 2013 Yes, they're aliases, but you have to worry about them. Take this code f...
- Brad Roberts (7/8) Nov 25 2013 There's only one effective way to keep things portable, and that's conti...
- qznc (5/12) Nov 25 2013 The gold standard: Every pull request (or every commit) should be
- Joseph Rushton Wakeling (6/9) Nov 25 2013 You have a challenge that (AFAIK, as things are) patches to the frontend...
- Jacob Carlborg (4/7) Nov 25 2013 And FreeBSD.
- nazriel (3/17) Nov 25 2013 And FreeBSD
- Joseph Rushton Wakeling (9/16) Nov 25 2013 You're quite right -- I was just thinking about underlying stuff along t...
- Jonathan M Davis (11/33) Nov 25 2013 Many people seem to just use int everywhere, and a lot of D code failed ...
- froglegs (4/5) Nov 25 2013 That isn't an error in D?
- Gary Willoughby (4/9) Nov 25 2013 Because `arr.length` returns a `size_t` value i would imagine
- Jonathan M Davis (16/24) Nov 25 2013 No. It's not a warning, and dmd is not big on warnings (and IMHO warning...
- froglegs (8/42) Nov 26 2013 I understand that it is converting a uint32 to a int32. My
- Joseph Rushton Wakeling (17/25) Nov 25 2013 Ack :-(
- IgorStepanov (20/21) Nov 25 2013 This code is not portable only on CTFE part. (All those float
- Iain Buclaw (24/40) Nov 25 2013 The following IEEE 'real' formats are currently supported:
- IgorStepanov (8/68) Nov 25 2013 I can't implement CTFE support of types more precise than x86
- Iain Buclaw (3/75) Nov 25 2013 Then test with a compiler that does have support in CTFE for floats
On 2013-11-24 11:38:25 +0000, Iain Buclaw said:https://github.com/D-Programming-Language/druntime/pull/663A link to pages of a pull extension for CTFE hashes. Care to clarify?
Nov 24 2013
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: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 103490da285999dR183https://github.com/D-Programming-Language/druntime/pull/663A link to pages of a pull extension for CTFE hashes. Care to clarify?
Nov 24 2013
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
On 2013-11-24 17:47:49 +0000, Andrej Mitrovic said:On 11/24/13, Johannes Pfau <nospam example.com> 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. 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? -ShammahWe 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
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
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
On Sunday, November 24, 2013 18:47:49 Andrej Mitrovic wrote:On 11/24/13, Johannes Pfau <nospam example.com> wrote: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 DavisWe 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
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
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
On Monday, November 25, 2013 00:34:31 ponce wrote:On Sunday, 24 November 2013 at 22:38:15 UTC, Jonathan M Davis wrote:Correct. I mistyped. Sorry about that. - Jonathan M DavisNo. 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
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:Isn't size_t unsigned and ptrdiff_t signed?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
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
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
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
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: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 DavisBut 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 25 2013
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
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
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: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.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
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
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
On Sunday, 24 November 2013 at 15:34:37 UTC, Shammah Chancellor wrote:On 2013-11-24 11:38:25 +0000, Iain Buclaw said:You only need to look as far as the FloatTraits template to then shake your head in misery. ;-)https://github.com/D-Programming-Language/druntime/pull/663A link to pages of a pull extension for CTFE hashes. Care to clarify?
Nov 24 2013
On Monday, November 25, 2013 09:25:46 Joseph Rushton Wakeling wrote:On 24/11/13 23:38, 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. 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 DavisNo. 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
On 11/24/13 3:38 AM, Iain Buclaw wrote:https://github.com/D-Programming-Language/druntime/pull/663There'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
On Monday, 25 November 2013 at 09:05:14 UTC, Brad Roberts wrote:On 11/24/13 3:38 AM, Iain Buclaw 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.https://github.com/D-Programming-Language/druntime/pull/663There'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.
Nov 25 2013
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
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
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:And MIPS, PPC, PPC64, SPARC :))))On 11/24/13 3:38 AM, Iain Buclaw wrote:The gold standard: Every pull request (or every commit) should be tested with DMD/LDC/GDC on x86/amd64/armhttps://github.com/D-Programming-Language/druntime/pull/663There'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.with Linux/Win/OSX.And FreeBSDThat is already 27 variants. Actually there should probably be more like with/without SSE.
Nov 25 2013
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
On Monday, November 25, 2013 10:40:11 Joseph Rushton Wakeling wrote:On 25/11/13 09:52, 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. 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.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 ... ?I'd be _very_ suspicious of any bitshifts that aren't done on types with a fixed size. - Jonathan M Davis
Nov 25 2013
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?int len = arr.length;
Nov 25 2013
On Monday, 25 November 2013 at 11:15:00 UTC, froglegs wrote: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.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?int len = arr.length;
Nov 25 2013
On Monday, November 25, 2013 12:14:59 froglegs wrote: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 DavisThat 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?int len = arr.length;
Nov 25 2013
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: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 DavisThat 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?int len = arr.length;
Nov 26 2013
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?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.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.
Nov 25 2013
On Sunday, 24 November 2013 at 11:38:27 UTC, Iain Buclaw wrote:https://github.com/D-Programming-Language/druntime/pull/663This 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
On 25 November 2013 21:44, IgorStepanov <wazar mail.ru> wrote:On Sunday, 24 November 2013 at 11:38:27 UTC, Iain Buclaw wrote: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.https://github.com/D-Programming-Language/druntime/pull/663This 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.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
On Monday, 25 November 2013 at 22:54:03 UTC, Iain Buclaw wrote:On 25 November 2013 21:44, IgorStepanov <wazar mail.ru> wrote: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.On Sunday, 24 November 2013 at 11:38:27 UTC, Iain Buclaw wrote: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.https://github.com/D-Programming-Language/druntime/pull/663This 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.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
On 25 November 2013 23:36, IgorStepanov <wazar mail.ru> wrote:On Monday, 25 November 2013 at 22:54:03 UTC, Iain Buclaw wrote: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)On 25 November 2013 21:44, IgorStepanov <wazar mail.ru> wrote: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.On Sunday, 24 November 2013 at 11:38:27 UTC, Iain Buclaw wrote: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.https://github.com/D-Programming-Language/druntime/pull/663This 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.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