digitalmars.D - Language features and reinterpret casts
- bearophile (14/14) Sep 20 2010 On Reddit I have read some people complain that D2 is a too much complex...
- klickverbot (2/4) Sep 20 2010 Are there any cases where (*cast(int*)&someFloat) does not fit the bill?
- bearophile (4/5) Sep 20 2010 I am not a C lawyer, but I think that too is undefined in C (and maybe D...
- Simen kjaeraas (8/12) Sep 21 2010 From your own link
- Bruno Medeiros (5/16) Nov 01 2010 That's not the same thing. Walter was referring to casting an int to a
- Bruno Medeiros (8/13) Nov 01 2010 In general, it is definitely undefined behavior in C, but that's because...
- Jesse Phillips (2/6) Sep 20 2010 I believe that defined behavior within an area where C is specified to b...
- Jonathan M Davis (10/23) Sep 20 2010 Well, since C doesn't define the behavior, D can do anything - including...
- bearophile (9/11) Sep 20 2010 It was an answer in a thread of mine where I have asked to remove some D...
- BCS (4/11) Sep 20 2010 I don't see how those apply to unions.
- Don (4/16) Sep 20 2010 It's going to be implementation defined behaviour (will depend on
- BCS (4/21) Sep 20 2010 --
- Don (5/27) Sep 21 2010 Definitely -- you'll grab the part of the mantissa, instead of the expon...
- bearophile (4/7) Sep 21 2010 I suggest to add something like a std.traits.ReinterpretCast template to...
- Jesse Phillips (3/20) Sep 21 2010 I remember that thread and even replied to it. I didn't see anything whe...
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=21901Are 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
bearophile <bearophileHUGS lycos.com> wrote:klickverbot: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." -- SimenAre 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).
Sep 21 2010
On 21/09/2010 09:23, Simen kjaeraas wrote:bearophile <bearophileHUGS lycos.com> wrote: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 Engineerklickverbot: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."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).
Nov 01 2010
On 21/09/2010 00:27, bearophile wrote:klickverbot: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 EngineerAre 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
Nov 01 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: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- 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.
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:I don't see how those apply to unions. -- ... <IXOYE><Why 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:
Sep 20 2010
BCS wrote:Hello bearophile,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.Jesse Phillips:I don't see how those apply to unions.Why 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:
Sep 20 2010
Hello Don,BCS wrote:Does that matter if the members are the same size?Hello bearophile,It's going to be implementation defined behaviour (will depend on endianness)Jesse Phillips:I don't see how those apply to unions.Why 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:but not undefined behaviour. BTW std.math heavily relies on reinterpret casting float->int.-- ... <IXOYE><
Sep 20 2010
BCS wrote:Hello Don,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).BCS wrote:Does that matter if the members are the same size?Hello bearophile,It's going to be implementation defined behaviour (will depend on endianness)Jesse Phillips:I don't see how those apply to unions.Why 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:but not undefined behaviour. BTW std.math heavily relies on reinterpret casting float->int.
Sep 21 2010
Hello Don,BCS wrote:How would that work? Can a system store ints big-endian and floats little-endian? -- ... <IXOYE><Hello Don,Definitely -- you'll grab the part of the mantissa, instead of the exponent.It's going to be implementation defined behaviour (will depend on endianness)Does that matter if the members are the same size?
Sep 21 2010
BCS wrote:Hello Don,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.BCS wrote:How would that work? Can a system store ints big-endian and floats little-endian?Hello Don,Definitely -- you'll grab the part of the mantissa, instead of the exponent.It's going to be implementation defined behaviour (will depend on endianness)Does that matter if the members are the same size?
Sep 21 2010
Hello Don,BCS wrote: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><Hello Don, 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
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