www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - To avoid some 32=>64 bit user code port bugs

reply bearophile <bearophileHUGS lycos.com> writes:
This shows many pitfalls regarding conversion of 32 bit code to 64, some of
them are relevant for D code too:
http://www.gamedev.net/reference/articles/article2767.asp


On 32 bit D systems this compiles with no errors, while on 64 bit D this
probably requires a cast:

size_t foo() { return -1; }
void main() {
    uint r = foo();
}

I'd like D to be designed to make 32=>64 porting as bug-free as possible, so
dmd may guard against some possible 64bit troubles even if the code is compiled
in 32 bit mode. So I think size_t=>uint may require a cast on 32 bit systems
too, so when the code gets compiled with the 64 bit dmd this error isn't
present.

---------------

With the 32 bit DMD this code works:

void main() {
    int x;
    int* ptr = &x;
    uint y = cast(uint)ptr;
    // ... usage of y
}


The cast() silences the compiler on 64 bit systems too, but on 64 bit systems
this may be more correct:
size_t value = cast(size_t)ptr;

A cast() is a way for the programmer to express the desire to punch a hole in
the type system, but in my opinion not all casts are equally unsafe. Some of
them are _more_ bug-prone than others. On 64 bit systems a pointer=>uint cast
is less safe than a pointer=>size_t cast or a pointer=>ptrdiff_t cast, because
it's a lossless transformation.

(In practice I think that a pointer=>uint is a bad thing even in 32 bit code,
when a sign is really necessary it's probably better to use ptrdiff_t on 32 bit
systems too).

So 64 bit DMD may show a warning for pointer=>uint casts, I don't know.

Bye,
bearophile
Aug 16 2010
next sibling parent Adam Ruppe <destructionator gmail.com> writes:
On 8/16/10, bearophile <bearophileHUGS lycos.com> wrote:
 So I think size_t=>uint may require a cast on 32
 bit systems too, so when the code gets compiled with the 64 bit dmd this
 error isn't present.
I don't think that's a good idea because of what you say later in your post: the cast punches a hole through the system. On 32 bit, the cast is certainly safe, but on 64 bit, it might not be, but the compiler won't complain. I think right now, size_t is an alias to uint. On 64 bit, it'll probably be an alias to ulong. That means assigning to uint won't compile, so it draws your attention to the line. You can look it over and decide if the cast is actually warranted or not. If you put the cast there in 32 bit, it will work and might silently break it later in 64 bit. Casts should be avoided whenever possible. Every required cast is another potential silent bug down the line.
 So 64 bit DMD may show a warning for pointer=>uint casts, I don't know.
That's probably a good idea.
Aug 16 2010
prev sibling next sibling parent reply Trass3r <un known.com> writes:
 So I think size_t=>uint may require a cast on 32 bit systems too,
 so when the code gets compiled with the 64 bit dmd this error isn't  
 present.
Well just make size_t a typedef instead of an alias.
Aug 16 2010
parent reply KennyTM~ <kennytm gmail.com> writes:
On Aug 16, 10 23:19, Trass3r wrote:
 So I think size_t=>uint may require a cast on 32 bit systems too,
 so when the code gets compiled with the 64 bit dmd this error isn't
 present.
Well just make size_t a typedef instead of an alias.
Isn't typedef being deprecated?
Aug 16 2010
parent reply Trass3r <un known.com> writes:
 Isn't typedef being deprecated?
Which brings us back to the task of augmenting the library-based alternative. I already started 2 threads about this.
Aug 16 2010
parent reply KennyTM~ <kennytm gmail.com> writes:
On Aug 17, 10 04:30, Trass3r wrote:
 Isn't typedef being deprecated?
Which brings us back to the task of augmenting the library-based alternative. I already started 2 threads about this.
Or size_t and ptrdiff_t could be made to be built-in types. (?)
Aug 16 2010
parent reply Trass3r <un known.com> writes:
 Or size_t and ptrdiff_t could be made to be built-in types. (?)
There's no justification for that. A proper way to define a strong typedef on the other hand is something that is really needed.
Aug 16 2010
parent reply KennyTM~ <kennytm gmail.com> writes:
On Aug 17, 10 05:34, Trass3r wrote:
 Or size_t and ptrdiff_t could be made to be built-in types. (?)
There's no justification for that. A proper way to define a strong typedef on the other hand is something that is really needed.
If size_t is a library-defined strong typedef instead of alias, what type should .sizeof return?
Aug 17 2010
next sibling parent Fawzi Mohamed <fawzi gmx.ch> writes:
On 17-ago-10, at 09:56, KennyTM~ wrote:

 On Aug 17, 10 05:34, Trass3r wrote:
 Or size_t and ptrdiff_t could be made to be built-in types. (?)
There's no justification for that. A proper way to define a strong typedef on the other hand is something that is really needed.
If size_t is a library-defined strong typedef instead of alias, what type should .sizeof return?
I brought it up several times, I think that the following changes would limit very much 32 -> 64 bugs and unsigned related bugs: 1) typedef like dfinition of size_t, ptrdiff_t *but* with implicit conversion ptrdiff_t-> size_t (a normal typedef without implicit cast would be a pain to use) 2) implicit casts signed-> unsigned should be final in the sense that after an implicit cast to an unsigned type *no* other implicit casts should be allowed (the idea being that an implicit cast to unsigned commits to a given bit pattern because it is equivalent to working mod 2**(8*T.sizeof)). maybe this is the right time for this to be re-considered? Fawzi
Aug 17 2010
prev sibling parent reply Trass3r <un known.com> writes:
 If size_t is a library-defined strong typedef instead of alias, what  
 type should .sizeof return?
Hmm good point, I don't know how it is handled currently.
Aug 17 2010
parent KennyTM~ <kennytm gmail.com> writes:
On Aug 17, 10 22:07, Trass3r wrote:
 If size_t is a library-defined strong typedef instead of alias, what
 type should .sizeof return?
Hmm good point, I don't know how it is handled currently.
Currently, .sizeof returns a uint, and size_t is defined as alias typeof(int.sizeof) size_t; inside object.di.
Aug 17 2010
prev sibling parent reply "Yao G." <nospamyao gmail.com> writes:
On Mon, 16 Aug 2010 09:40:15 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 This shows many pitfalls regarding conversion of 32 bit code to 64, some  
 of them are relevant for D code too:
 http://www.gamedev.net/reference/articles/article2767.asp
Thanks for sharing this article bearophile. It's actually pretty good and comprehensive. -- Yao G.
Aug 16 2010
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Here are some other articles about problems with 32bit>64bit porting if
anyone is interested:

http://www.viva64.com/content/articles/64-bit-development/?f=64-bit-arithmetic.html&lang=en&content=64-bit-development
http://www.viva64.com/content/articles/64-bit-development/?f=TrapsDetection.html&lang=en&content=64-bit-development
http://www.viva64.com/content/articles/64-bit-development/?f=size_t_and_ptrdiff_t.html&lang=en&content=64-bit-development

On Mon, Aug 16, 2010 at 10:19 PM, Yao G. <nospamyao gmail.com> wrote:

 On Mon, 16 Aug 2010 09:40:15 -0500, bearophile <bearophileHUGS lycos.com>
 wrote:

  This shows many pitfalls regarding conversion of 32 bit code to 64, some
 of them are relevant for D code too:
 http://www.gamedev.net/reference/articles/article2767.asp
Thanks for sharing this article bearophile. It's actually pretty good and comprehensive. -- Yao G.
Aug 16 2010
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
And some more:
http://www.viva64.com/content/articles/64-bit-development/?f=64-bit-migration-7-steps.html&lang=en&content=64-bit-development
http://www.viva64.com/content/articles/64-bit-development/?f=20_issues_of_porting_C++_code_on_the_64-bit_platform.html&lang=en&content=64-bit-development


On Mon, Aug 16, 2010 at 10:23 PM, Andrej Mitrovic <
andrej.mitrovich gmail.com> wrote:

 Here are some other articles about problems with 32bit>64bit porting if
 anyone is interested:


 http://www.viva64.com/content/articles/64-bit-development/?f=64-bit-arithmetic.html&lang=en&content=64-bit-development

 http://www.viva64.com/content/articles/64-bit-development/?f=TrapsDetection.html&lang=en&content=64-bit-development

 http://www.viva64.com/content/articles/64-bit-development/?f=size_t_and_ptrdiff_t.html&lang=en&content=64-bit-development


 On Mon, Aug 16, 2010 at 10:19 PM, Yao G. <nospamyao gmail.com> wrote:

 On Mon, 16 Aug 2010 09:40:15 -0500, bearophile <bearophileHUGS lycos.com>
 wrote:

  This shows many pitfalls regarding conversion of 32 bit code to 64, some
 of them are relevant for D code too:
 http://www.gamedev.net/reference/articles/article2767.asp
Thanks for sharing this article bearophile. It's actually pretty good and comprehensive. -- Yao G.
Aug 16 2010