Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
September 20, 2006 size_t, size_t, wherefore art thou aliased? | ||||
---|---|---|---|---|
| ||||
(For the early-modern-English-impaired, "wherefore art thou aliased" means "why are you aliased") In the process of porting GDC to x86_64 (which has actually been somewhat successful, but more on that later), I've discovered what I consider to be a fairly significant problem. Because size_t is aliased (and also partially because DDoc follows aliases apparently), there is a tendency to use uint instead of size_t, and no error or even feedback if you do! For example, std.socketstream overrides: size_t readBlock(void* _buffer, size_t size) with uint readBlock(void* _buffer, uint size) Ouch! Works fine on 32-bit systems, but totally fails on 64-bit systems, and the writer has no way of knowing there's a bug until he tries to compile it on a 64-bit system! The biggest problem here is with overriding (as in the above example), where it'll override properly on 32-bit but improperly on 64-bit systems. The folks on #d and I have created several possible solutions. Our original thought was to make size_t (and ptrdiff_t) typedefs instead of aliases - this would at least require no change to the language proper. Unfortunately, this makes assigning values to size_t and ptrdiff_t obnoxious, since it only implicitly casts one way (not the way that's helpful here). Secondly, size_t and ptrdiff_t could be compiler-defined types, rather than aliased types. This would make the implicit casting come out right, but is sort of ugly. Finally, the preferred option seems to be a sort of weak typedef. Basically, this would be a typedef, but with implicit casting both ways. So, [u]ints, [u]longs, size_ts and ptrdiff_ts would all play nicely together, but overrides would not be happy if improperly defined. The most unfortunate thing about this is that there's virtually no way for a programmer on a 32-bit system to know when they've ran into a bug like this. Yuck. - Gregor Richards |
September 20, 2006 Re: size_t, size_t, wherefore art thou aliased? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gregor Richards | > Unfortunately, this makes assigning values to size_t and ptrdiff_t obnoxious, since it only implicitly casts one way (not the way that's helpful here).
typedef int test_t;
void main(){
test_t x = 2;
}
works just fine. Am I missing something?
L.
|
September 20, 2006 Re: size_t, size_t, wherefore art thou aliased? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lionello Lunesu | Lionello Lunesu wrote:
>> Unfortunately, this makes assigning values to size_t and ptrdiff_t obnoxious, since it only implicitly casts one way (not the way that's helpful here).
>
> typedef int test_t;
> void main(){
> test_t x = 2;
> }
>
> works just fine. Am I missing something?
>
> L.
>
>
typedef int test_t;
int main()
{
test_t x;
int y = 2;
x = y;
return 0;
}
Actually, the absolutely precise solution would be a precise reversal of the typedef rules - size_t should accept ints/longs/etc, but ints/longs/etc should not accept size_t.
- Gregor Richards
|
September 21, 2006 Re: size_t, size_t, wherefore art thou aliased? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gregor Richards | On Wed, 20 Sep 2006 08:15:29 -0700, Gregor Richards <Richards@codu.org> wrote: >The most unfortunate thing about this is that there's virtually no way for a programmer on a 32-bit system to know when they've ran into a bug like this. Yuck. In Visual C++, you get warnings about size issues even when they don't exist. VC++ will complain if it thinks the type you specified might be a 64 bit type in the future, and your using it somewhere 32-bitty for instance. Maybe a similar (optional) compiler warning? The compiler could flag 'this is being treated as an uint32_t/uint64_t but it was originally size_t' and give warnings as needed? -- Remove 'wants' and 'nospam' from e-mail. |
September 21, 2006 Re: size_t, size_t, wherefore art thou aliased? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gregor Richards | I think I don't really understand the issue, but I'm gonna throw in my 2 cents anyway ... even though it might sound pretty stupid:
Wouldn't a versioned alias declaration solve this?
version( X32 )
{
alias something ...
}
version( X64 )
{
alias something else ...
}
Gregor Richards wrote:
> (For the early-modern-English-impaired, "wherefore art thou aliased" means "why are you aliased")
>
> In the process of porting GDC to x86_64 (which has actually been somewhat successful, but more on that later), I've discovered what I consider to be a fairly significant problem.
>
> Because size_t is aliased (and also partially because DDoc follows aliases apparently), there is a tendency to use uint instead of size_t, and no error or even feedback if you do!
>
> For example, std.socketstream overrides:
>
> size_t readBlock(void* _buffer, size_t size)
>
> with
>
> uint readBlock(void* _buffer, uint size)
>
> Ouch! Works fine on 32-bit systems, but totally fails on 64-bit systems, and the writer has no way of knowing there's a bug until he tries to compile it on a 64-bit system! The biggest problem here is with overriding (as in the above example), where it'll override properly on 32-bit but improperly on 64-bit systems.
>
> The folks on #d and I have created several possible solutions.
>
> Our original thought was to make size_t (and ptrdiff_t) typedefs instead of aliases - this would at least require no change to the language proper. Unfortunately, this makes assigning values to size_t and ptrdiff_t obnoxious, since it only implicitly casts one way (not the way that's helpful here).
>
> Secondly, size_t and ptrdiff_t could be compiler-defined types, rather than aliased types. This would make the implicit casting come out right, but is sort of ugly.
>
> Finally, the preferred option seems to be a sort of weak typedef. Basically, this would be a typedef, but with implicit casting both ways. So, [u]ints, [u]longs, size_ts and ptrdiff_ts would all play nicely together, but overrides would not be happy if improperly defined.
>
> The most unfortunate thing about this is that there's virtually no way for a programmer on a 32-bit system to know when they've ran into a bug like this. Yuck.
>
> - Gregor Richards
|
September 23, 2006 Re: size_t, size_t, wherefore art thou aliased? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hasan Aljudy | Hasan Aljudy schrieb:
> I think I don't really understand the issue, but I'm gonna throw in my 2 cents anyway ... even though it might sound pretty stupid:
>
> Wouldn't a versioned alias declaration solve this?
>
> version( X32 )
> {
> alias something ...
> }
> version( X64 )
> {
> alias something else ...
> }
>
I think this is exactly like size_t is defined. And the problem Gregor describes is a result from that.
|
Copyright © 1999-2021 by the D Language Foundation