digitalmars.D - Language features and reinterpret casts
- bearophile <bearophileHUGS lycos.com> Sep 20 2010
- klickverbot <see klickverbot.at> Sep 20 2010
- bearophile <bearophileHUGS lycos.com> Sep 20 2010
- Bruno Medeiros <brunodomedeiros+spam com.gmail> Nov 01 2010
- Bruno Medeiros <brunodomedeiros+spam com.gmail> Nov 01 2010
- "Simen kjaeraas" <simen.kjaras gmail.com> Sep 21 2010
- Jesse Phillips <jessekphillips+D gmail.com> Sep 20 2010
- Jonathan M Davis <jmdavisProg gmx.com> Sep 20 2010
- bearophile <bearophileHUGS lycos.com> Sep 20 2010
- BCS <none anon.com> Sep 20 2010
- Don <nospam nospam.com> Sep 20 2010
- BCS <none anon.com> Sep 20 2010
- Don <nospam nospam.com> Sep 21 2010
- BCS <none anon.com> Sep 21 2010
- Don <nospam nospam.com> Sep 21 2010
- BCS <none anon.com> Sep 21 2010
- bearophile <bearophileHUGS lycos.com> Sep 21 2010
- Jesse Phillips <jessekphillips+D gmail.com> Sep 21 2010
On Reddit I have read some people complain that D2 is a too much complex language because it has too many features. Feature "count" increases a language complexity, but most of the complexity comes from other sources, like unwanted interactions between features, messy feature semantics, unspecified behaviour in corner cases, special cases, special cases of special cases, etc. But tidy features able to solve a defined class of problems usually decrease the amount of work of the programmer. Recently Bradley Mitchell in D.learn newsgroup has tried to implement the Quake fast inverse square root algorithm in D, and has found D lack the C++ reinterpret cast: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=21901 If you use the current dmd you are able to solve this problem using a union to reinterpret the bits. But: - C Standard says that assigning to one member of a union and then accessing a different member is undefined behaviour. - GCC is a practical compiler, so it has the -fno-strict-aliasing switch, that allows to use that trick. See "-Wstrict-aliasing" and: http://stackoverflow.com/questions/2906365/gcc-strict-aliasing-and-casting-through-a-union - Walter said that regarding such union semantics D acts as C. So that union trick will break with other future D compilers. The need to perform a reinterpret cast is uncommon, I don't need it in Python, but it does happen in a system language. So all this situation looks silly to me. A modern language as D can't force programmer to use undefined tricks to do something uncommon but licit. Adding a feature here increases language complexity a little, but removes troubles and makes coding simpler (no need to remember or invent tricks), safer (you are sure the compiler will act as you want), more explicit (because the person that reads the code doesn't need to reverse engineer the trick), more efficient (because if you have to use -fno-strict-aliasing it may reduce performance a little). So unless you have a different solution, I think D is better with a reinterpret_cast(). An alternative solution is to put a standard reinterpretCast!(U)(x) into Phobos2, and then let people that implement future D compilers define its semantics correctly for that compiler. So the user code that uses this template is portable, safe, efficient, explicit in its purpose. Bye, bearophile
Sep 20 2010
On 9/20/10 11:52 PM, bearophile wrote:Recently Bradley Mitchell in D.learn newsgroup has tried to implement the Quake fast inverse square root algorithm in D, and has found D lack the C++ reinterpret cast: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=21901
Are there any cases where (*cast(int*)&someFloat) does not fit the bill?
Sep 20 2010
klickverbot:Are there any cases where (*cast(int*)&someFloat) does not fit the bill?
I am not a C lawyer, but I think that too is undefined in C (and maybe D too). Bye, bearophile
Sep 20 2010
On 21/09/2010 00:27, bearophile wrote:klickverbot:Are there any cases where (*cast(int*)&someFloat) does not fit the bill?
I am not a C lawyer, but I think that too is undefined in C (and maybe D too). Bye, bearophile
In general, it is definitely undefined behavior in C, but that's because an int in C can be bigger than a float, so you could be reading memory out of bounds with that. If sizeof(int) == sizeof(float), then it's legal in C. Similarly, I think it is legal in D. -- Bruno Medeiros - Software Engineer
Nov 01 2010
On 21/09/2010 09:23, Simen kjaeraas wrote:bearophile <bearophileHUGS lycos.com> wrote:klickverbot:Are there any cases where (*cast(int*)&someFloat) does not fit the bill?
I am not a C lawyer, but I think that too is undefined in C (and maybe D too).
From your own link (http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=109033): "I don't see any way to make conversions between pointers and ints implementation defined, and make dereferencing a pointer coming from some int anything but undefined behavior."
That's not the same thing. Walter was referring to casting an int to a pointer, but the above is casting a _float pointer_ to an _int pointer_. -- Bruno Medeiros - Software Engineer
Nov 01 2010
bearophile <bearophileHUGS lycos.com> wrote:klickverbot:Are there any cases where (*cast(int*)&someFloat) does not fit the bill?
I am not a C lawyer, but I think that too is undefined in C (and maybe D too).
From your own link (http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=109033): "I don't see any way to make conversions between pointers and ints implementation defined, and make dereferencing a pointer coming from some int anything but undefined behavior." -- Simen
Sep 21 2010
bearophile Wrote:- C Standard says that assigning to one member of a union and then accessing a different member is undefined behaviour. - GCC is a practical compiler, so it has the -fno-strict-aliasing switch, that allows to use that trick. See "-Wstrict-aliasing" and: http://stackoverflow.com/questions/2906365/gcc-strict-aliasing-and-casting-through-a-union - Walter said that regarding such union semantics D acts as C. So that union trick will break with other future D compilers.
I believe that defined behavior within an area where C is specified to be undefined is completely in line with operating as C does. But where does Walter say Unions act as C in this case? Why not, define the behavior and leave it.
Sep 20 2010
On Monday, September 20, 2010 18:21:53 Jesse Phillips wrote:bearophile Wrote:- C Standard says that assigning to one member of a union and then accessing a different member is undefined behaviour. - GCC is a practical compiler, so it has the -fno-strict-aliasing switch, that allows to use that trick. See "-Wstrict-aliasing" and: http://stackoverflow.com/questions/2906365/gcc-strict-aliasing-and-casti ng-through-a-union - Walter said that regarding such union semantics D acts as C. So that union trick will break with other future D compilers.
I believe that defined behavior within an area where C is specified to be undefined is completely in line with operating as C does. But where does Walter say Unions act as C in this case? Why not, define the behavior and leave it.
Well, since C doesn't define the behavior, D can do anything - including using behavior that it defines and considers entirely consistent. So, as long as it's D code, I see no reason why D can't use the same constructs as C code but have things which are undefined in C be defined in D. The only problem is if you port code from D to C, but that's not exactly something that we're generally worried about. Overall though, I get the impression that Walter's goal is to get as close to having no undefined behavior in D as he reasonably can. Whether the behavior is defined in another language or not isn't particularly relevant. - Jonathan M Davis
Sep 20 2010
Jesse Phillips:But where does Walter say Unions act as C in this case?
It was an answer in a thread of mine where I have asked to remove some D undefined behaviours derived from C. This is the thread start: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=108978Why not, define the behavior and leave it.
This was the original purpose of my thread, but Walter has explained me that this is not possible for the unions: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=109033 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=109058 Bye, bearophile
Sep 20 2010
Hello bearophile,Jesse Phillips:Why not, define the behavior and leave it.
me that this is not possible for the unions:
I don't see how those apply to unions. -- ... <IXOYE><
Sep 20 2010
BCS wrote:Hello bearophile,Jesse Phillips:Why not, define the behavior and leave it.
me that this is not possible for the unions:
I don't see how those apply to unions.
It's going to be implementation defined behaviour (will depend on endianness) but not undefined behaviour. BTW std.math heavily relies on reinterpret casting float->int.
Sep 20 2010
Hello Don,BCS wrote:Hello bearophile,Jesse Phillips:Why not, define the behavior and leave it.
me that this is not possible for the unions:
endianness)
Does that matter if the members are the same size?but not undefined behaviour. BTW std.math heavily relies on reinterpret casting float->int.
... <IXOYE><
Sep 20 2010
BCS wrote:Hello Don,BCS wrote:Hello bearophile,Jesse Phillips:Why not, define the behavior and leave it.
me that this is not possible for the unions:
endianness)
Does that matter if the members are the same size?
Definitely -- you'll grab the part of the mantissa, instead of the exponent. It should however only be hardware-and-OS-dependent, rather than compiler-dependent. (It can be OS-dependent because of different padding rules).but not undefined behaviour. BTW std.math heavily relies on reinterpret casting float->int.
Sep 21 2010
Hello Don,BCS wrote:Hello Don,It's going to be implementation defined behaviour (will depend on endianness)
exponent.
How would that work? Can a system store ints big-endian and floats little-endian? -- ... <IXOYE><
Sep 21 2010
BCS wrote:Hello Don,BCS wrote:Hello Don,It's going to be implementation defined behaviour (will depend on endianness)
exponent.
How would that work? Can a system store ints big-endian and floats little-endian?
Not sure. My limited understanding is that with on PowerPC, Altivec can use big-endian floats, even when the PPC is set to little-endian mode. Could be wrong, though. In any case, for 80-bit reals, there is no int which is the same size.
Sep 21 2010
Hello Don,BCS wrote:Hello Don, How would that work? Can a system store ints big-endian and floats little-endian?
can use big-endian floats, even when the PPC is set to little-endian mode. Could be wrong, though. In any case, for 80-bit reals, there is no int which is the same size.
So how tightly can we define it without losing to much? If we define a union where all the members are of the same size to, overplayed exactly and requiter the to consistent use of big/little-endian, would that make anything horribly inefficient? Even if that rules out PPC vector ops, I don't think that would be a big issue. -- ... <IXOYE><
Sep 21 2010
Don:It's going to be implementation defined behaviour (will depend on endianness) but not undefined behaviour. BTW std.math heavily relies on reinterpret casting float->int.
I suggest to add something like a std.traits.ReinterpretCast template to Phobos and use only it in Phobos modules and user code. This helps readability and will help future more aggressively optimizing D compilers too. Bye, bearophile
Sep 21 2010
I remember that thread and even replied to it. I didn't see anything where Walter said Unions behave as C. Nor was there anything where Walter said he would not define C undefined behavior. All he said was, for the cases presented, there was no way to define the behavior or didn't know what defined behavior would be. I don't know if it would be reasonable to define the behavior of Union for this, but since it currently works in D I assume it can be defined to work that way. bearophile Wrote:Jesse Phillips:But where does Walter say Unions act as C in this case?
It was an answer in a thread of mine where I have asked to remove some D undefined behaviours derived from C. This is the thread start: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=108978Why not, define the behavior and leave it.
This was the original purpose of my thread, but Walter has explained me that this is not possible for the unions: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=109033 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=109058 Bye, bearophile
Sep 21 2010









Bruno Medeiros <brunodomedeiros+spam com.gmail> 