digitalmars.D - size_t + ptrdiff_t
- Manu (14/14) Feb 19 2012 Okay, so it came up a couple of times, but the questions is, what are we
- Stewart Gordon (9/15) Feb 19 2012 The whole point of size_t and ptrdiff_t is that they are integer types t...
- Manu (11/34) Feb 19 2012 You also need a type that knows the native word size of the machine, not
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (5/37) Feb 19 2012 Also, fun fact: Even on x86, pointers aren't necessarily 32- or 64-bit
- Vladimir Panteleev (2/3) Feb 19 2012 When is this not true? I can only think of 16-bit far pointers.
- Daniel Murphy (3/6) Feb 19 2012 8-bit embedded quite often has 16-bit pointers.
- Stewart Gordon (10/17) Feb 19 2012 And has an 8-bit size_t?
- Manu (14/18) Feb 19 2012 Ignoring small embedded systems (for which it is almost always true), so...
- Walter Bright (4/20) Feb 19 2012 What I think you're arguing for is a "most efficient" int size, which pr...
- Vladimir Panteleev (4/13) Feb 21 2012 I know there are many systems with mismatching machine word and
- Artur Skawina (22/39) Feb 19 2012 not to mention linux - x32 (https://sites.google.com/site/x32abi/)
-
Stewart Gordon
(6/8)
Feb 19 2012
- Manu (7/16) Feb 19 2012 You can't imagine any situation where you might want to know how big an ...
-
Stewart Gordon
(8/10)
Feb 19 2012
- Manu (12/24) Feb 19 2012 In many cases you wouldn't need to know anything other than that.
-
Stewart Gordon
(13/18)
Feb 19 2012
- Manu (15/40) Feb 19 2012 well ssize_t is an already established compliment to size_t, I guess it'...
- Walter Bright (4/12) Feb 19 2012 I really think that simply adding c_int and c_uint to core.stdc.config w...
- Artur Skawina (5/17) Feb 19 2012 64bit platforms, depending on the definition of nativeInt.
- Manu (3/21) Feb 20 2012 ? I must have misunderstood something... I've never seen a 64bit C compi...
- Walter Bright (2/4) Feb 20 2012 What are you using in C code for a most efficient integer type?
- Manu (8/14) Feb 20 2012 #ifdef. No 2 C compilers ever seem to agree.
- Regan Heath (28/49) Feb 20 2012 I can imagine situations where you want to explicitly have a numeric typ...
- Kevin Cox (4/54) Feb 20 2012 What if te compiler was allowed to optimist to larger types? The only
- Walter Bright (3/9) Feb 20 2012 I think you're probably best off for now by doing your own alias for it.
- James Miller (34/47) Feb 20 2012 I don't know much about what is considered 'standard C', non x86
- Artur Skawina (17/33) Feb 21 2012 It's signed, unlike the unsigned 'size_t'.
- Walter Bright (4/7) Feb 21 2012 And, in fact, object.di contains:
- Iain Buclaw (9/18) Feb 21 2012 d
- Manu (15/27) Feb 21 2012 I don't know about you, but I very rarely get to work with a C compiler
- Walter Bright (6/18) Feb 21 2012 The C99 Standard sez:
- Stewart Gordon (4/7) Feb 22 2012 And what does it say about what type the sizeof operator returns?
- Sean Kelly (4/9) Feb 20 2012 I can't answer for Manu, but I imagine one should probably use =
- Jacob Carlborg (6/29) Feb 20 2012 According to Wikipedia, two out of four 64-bit data models uses 64bit
- Timon Gehr (5/19) Feb 19 2012 Currently, size_t is defined to be what you call ptr_t, ptrdiff_t is
- Manu (15/40) Feb 19 2012 It is just as unportable as size_t its self. The reason you need it is t...
- Timon Gehr (24/69) Feb 19 2012 Note that I agree that getting the terminology straight would be an
- Manu (22/67) Feb 19 2012 What about pointer arithmetic? Interaction with C/C++ code? Writing OS
- Iain Buclaw (7/50) Feb 20 2012 gdc offers __builtin_machine_(u)int for word size, and
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (4/54) Feb 20 2012 IMHO, it should be.
- Manu (15/72) Feb 20 2012 That's beautiful though! Can we alias them, and produce a true D type th...
- Iain Buclaw (5/84) Feb 20 2012 Well, as Walter said, these could be aliased in core.stdc.config.
- Manu (2/102) Feb 20 2012 I don't think they are 'standard c' though ;)
- Iain Buclaw (15/129) Feb 20 2012 OK, I'm just having a trudge through druntime:
-
Stewart Gordon
(5/6)
Feb 20 2012
- Johannes Pfau (5/13) Feb 20 2012 Exactly what's written there, c_long and c_ulong always match the C
- Stewart Gordon (7/10) Feb 21 2012 So in other words, it just means whatever somebody has decreed that the ...
- Walter Bright (3/5) Feb 21 2012 Probably.
- Jacob Carlborg (5/10) Feb 21 2012 Wouldn't that always be a "long" in D? Or is it the same as with "long"
- Stewart Gordon (8/14) Feb 22 2012 long in D is 64 bits.
- Manu (22/42) Feb 22 2012 The C standard is completely irrelevant to D, and should not be consider...
- Jacob Carlborg (12/18) Feb 20 2012 Simplified:
- Juan Manuel Cabo (30/33) Feb 21 2012 That is so good! Thanks!
- Iain Buclaw (5/6) Feb 21 2012 Eh?
- Juan Manuel Cabo (11/20) Feb 21 2012 All the type sizes vary in broken ways in C. The only sane way
- Sean Kelly (6/17) Feb 21 2012 size_t is intended to be the C representation. I very much do not want ...
- Juan Manuel Cabo (17/33) Feb 21 2012 Hahah, hold your jaw because it might drop:
- Juan Manuel Cabo (6/49) Feb 21 2012 I'm sorry, my snippet is wrong. It's a bit more complicated than what I ...
- Sean Kelly (5/11) Feb 21 2012 I think this is actually a good thing, since working with unsigned =
- Juan Manuel Cabo (19/20) Feb 21 2012 Yes, I would prefer that msb bit to be the sign too, but behavior might ...
- Manu (6/26) Feb 22 2012 Actually, it doesn't.
- Walter Bright (3/5) Feb 21 2012 Which is correct.
- Jonathan M Davis (4/11) Feb 21 2012 Yes, but __int64 is a signed integeral type, whereas size_t in D is an
- Walter Bright (2/12) Feb 21 2012 Ah, I see.
-
Stewart Gordon
(6/8)
Feb 21 2012
- Juan Manuel Cabo (15/26) Feb 21 2012 I just went to see a standard draft (http://www.clc-wiki.net/wiki/the_C_...
- Juan Manuel Cabo (10/12) Feb 21 2012 size_t being the typeof sizeof() expressions, tell you the upper bound
- Walter Bright (2/6) Feb 21 2012 size_t was 16 bits on all 16 bit memory models except the 'huge' one.
- Don Clugston (3/10) Feb 22 2012 I expected that for ptrdiff_t, but for size_t as well?
- Manu (2/16) Feb 22 2012 I've worked on platforms where sizeof(void*) was smaller than sizeof(siz...
- Manu (14/155) Feb 20 2012 It seems the problem is already MUCH worse than in D already :( .. this ...
- Johannes Pfau (5/179) Feb 20 2012 That's exactly what those types are for and that's the reason they're
- Sean Kelly (16/41) Feb 20 2012 https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/...
- Manu (2/39) Feb 20 2012 What about intptr_t/uintptr_t, are they builtins, or in core.stdc?
- Sean Kelly (8/10) Feb 20 2012 core.stdc. The only aliases that currently exist are defined in =
- kennytm (4/9) Feb 19 2012 sizediff_t (currently just aliased to ptrdiff_t but the link could be
- Manu (2/11) Feb 19 2012 O_o .. how is this different to size_t now? Why the redundant alias?
- Artur Skawina (8/25) Feb 19 2012 C compatibility?
- Stewart Gordon (7/14) Feb 19 2012 Why would you want to use meaningless type aliases defined in the C head...
- Artur Skawina (5/19) Feb 19 2012 That's how it can be used in *C*.
- Stewart Gordon (5/9) Feb 20 2012 IINM, C calling conventions care only about the size of a type, not the ...
- Manu (13/68) Feb 20 2012 No, this would be very very bad. People would use 'int' out of habit in
- Artur Skawina (11/75) Feb 20 2012 Explicitly sized types (ie u32 and friends) is what should be used by de...
Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fit the rest of the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code written using the incorrect types. Some time needs to be taken to correct phobos too I guess.
Feb 19 2012
On 19/02/2012 14:59, Manu wrote:Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption.The whole point of size_t and ptrdiff_t is that they are integer types that span the address space. So that the size of an allocated block of memory (and consequently, the number of elements in an array) is bound to fit in a size_t, and the displacement between two memory locations is bound to fit in a ptrdiff_t. What would this "register size" type you are proposing be for, exactly? <snip>There is also the problem that there is lots of code written using the incorrect types.<snip> Like what?
Feb 19 2012
On 19 February 2012 17:09, Stewart Gordon <smjg_1998 yahoo.com> wrote:On 19/02/2012 14:59, Manu wrote:You also need a type that knows the native word size of the machine, not just a pointer width. If size_t should be the pointer size, then there needs to be some other type that specifies the register width of the architecture.Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption.The whole point of size_t and ptrdiff_t is that they are integer types that span the address space. So that the size of an allocated block of memory (and consequently, the number of elements in an array) is bound to fit in a size_t, and the displacement between two memory locations is bound to fit in a ptrdiff_t. What would this "register size" type you are proposing be for, exactly?<snip> There is also the problem that there is lots of code written using theThere is code that assumes size_t is the width of the pointer, and other code that assumes size_t is the width of the native int. Only one of those is correct, whichever you declare it to be, and another type needs to be invented to define the other. It is common that pointers are the same width as the int regs, but there are many architectures where it's not true.incorrect types.<snip> Like what?
Feb 19 2012
On 19-02-2012 16:26, Manu wrote:On 19 February 2012 17:09, Stewart Gordon <smjg_1998 yahoo.com <mailto:smjg_1998 yahoo.com>> wrote: On 19/02/2012 14:59, Manu wrote: Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. The whole point of size_t and ptrdiff_t is that they are integer types that span the address space. So that the size of an allocated block of memory (and consequently, the number of elements in an array) is bound to fit in a size_t, and the displacement between two memory locations is bound to fit in a ptrdiff_t. What would this "register size" type you are proposing be for, exactly? You also need a type that knows the native word size of the machine, not just a pointer width. If size_t should be the pointer size, then there needs to be some other type that specifies the register width of the architecture. <snip> There is also the problem that there is lots of code written using the incorrect types. <snip> Like what? There is code that assumes size_t is the width of the pointer, and other code that assumes size_t is the width of the native int. Only one of those is correct, whichever you declare it to be, and another type needs to be invented to define the other. It is common that pointers are the same width as the int regs, but there are many architectures where it's not true.Also, fun fact: Even on x86, pointers aren't necessarily 32- or 64-bit wide - in kernel space. :) -- - Alex
Feb 19 2012
On Sunday, 19 February 2012 at 15:26:27 UTC, Manu wrote:There is code that assumes size_t is the width of the pointerWhen is this not true? I can only think of 16-bit far pointers.
Feb 19 2012
"Vladimir Panteleev" <vladimir thecybershadow.net> wrote in message news:valucopzdhxdjymkgvuq forum.dlang.org...On Sunday, 19 February 2012 at 15:26:27 UTC, Manu wrote:8-bit embedded quite often has 16-bit pointers.There is code that assumes size_t is the width of the pointerWhen is this not true? I can only think of 16-bit far pointers.
Feb 19 2012
On 19/02/2012 16:07, Daniel Murphy wrote:"Vladimir Panteleev"<vladimir thecybershadow.net> wrote in message news:valucopzdhxdjymkgvuq forum.dlang.org...And has an 8-bit size_t? Just found the bit I read before and was trying to find again http://www.dlang.org/portability.html "Use size_t as an alias for an unsigned integral type that can span the address space. Array indices should be of type size_t." Of course, anything below 32-bit is irrelevant to D, but according to cplusplus.com size_t is defined to be the type returned by sizeof. But where it explains sizeof it doesn't state what type that is, and I don't know what the C or C++ standard says about it. Stewart.On Sunday, 19 February 2012 at 15:26:27 UTC, Manu wrote:8-bit embedded quite often has 16-bit pointers.There is code that assumes size_t is the width of the pointerWhen is this not true? I can only think of 16-bit far pointers.
Feb 19 2012
On 19 February 2012 18:03, Vladimir Panteleev <vladimir thecybershadow.net>wrote:On Sunday, 19 February 2012 at 15:26:27 UTC, Manu wrote:Ignoring small embedded systems (for which it is almost always true), some that immediately come to mind: NaCl (Google Native Client) - x64 arch, 32bit pointers ... <- of immediate concern to me PPC based consoles; PS3, X360, Wii, WiiU (not released yet) - 64bit, all 32bit pointers Android, and probably iOS; 64bit ARM chips - will certainly not fork the OS to use 64bit pointers word/pointer width mismatch does happen, even if you try to argue it's uncommon, the language MUST be able to express these architectures. It's not an optional fix. Just need to name them properly, and correct existing code.There is code that assumes size_t is the width of the pointerWhen is this not true? I can only think of 16-bit far pointers.
Feb 19 2012
On 2/19/2012 8:23 AM, Manu wrote:On 19 February 2012 18:03, Vladimir Panteleev <vladimir thecybershadow.net <mailto:vladimir thecybershadow.net>> wrote: On Sunday, 19 February 2012 at 15:26:27 UTC, Manu wrote: There is code that assumes size_t is the width of the pointer When is this not true? I can only think of 16-bit far pointers. Ignoring small embedded systems (for which it is almost always true), some that immediately come to mind: NaCl (Google Native Client) - x64 arch, 32bit pointers ... <- of immediate concern to me PPC based consoles; PS3, X360, Wii, WiiU (not released yet) - 64bit, all 32bit pointers Android, and probably iOS; 64bit ARM chips - will certainly not fork the OS to use 64bit pointersOn these it appears that size_t will be (and should be) the pointer width.word/pointer width mismatch does happen, even if you try to argue it's uncommon, the language MUST be able to express these architectures. It's not an optional fix. Just need to name them properly, and correct existing code.What I think you're arguing for is a "most efficient" int size, which probably would be core.stdc.config.c_int, c_uint.
Feb 19 2012
On Sunday, 19 February 2012 at 16:23:50 UTC, Manu wrote:On 19 February 2012 18:03, Vladimir Panteleev <vladimir thecybershadow.net>wrote:I know there are many systems with mismatching machine word and pointer size. I asked about cases where size_t.sizeof != (void*).sizeof.On Sunday, 19 February 2012 at 15:26:27 UTC, Manu wrote:word/pointer width mismatch does happenThere is code that assumes size_t is the width of the pointerWhen is this not true? I can only think of 16-bit far pointers.
Feb 21 2012
On 02/19/12 17:23, Manu wrote:On 19 February 2012 18:03, Vladimir Panteleev <vladimir thecybershadow.net <mailto:vladimir thecybershadow.net>> wrote: On Sunday, 19 February 2012 at 15:26:27 UTC, Manu wrote: There is code that assumes size_t is the width of the pointer When is this not true? I can only think of 16-bit far pointers. Ignoring small embedded systems (for which it is almost always true), some that immediately come to mind: NaCl (Google Native Client) - x64 arch, 32bit pointers ... <- of immediate concern to me PPC based consoles; PS3, X360, Wii, WiiU (not released yet) - 64bit, all 32bit pointers Android, and probably iOS; 64bit ARM chips - will certainly not fork the OS to use 64bit pointersnot to mention linux - x32 (https://sites.google.com/site/x32abi/) But 'size_t' is the size of an object -- so sizeof(size_t)==sizeof(void*) is a pretty safe assumption. It would be a bit hard to work with objects that are larger than the address space covered by the pointer... Is any of the above platforms using segmentation tricks and is sizeof(char*-char*)>sizeof(char*)? I think you mean "native_int" - something that D is missing. On 02/19/12 19:07, Timon Gehr wrote:Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.eg any time you don't want to artificially restrict the size to less than the native one, not use a type wider than the hw efficiently handles or need C compatibility. Yes, you can use 'static if' and 'version' tricks, but that's inconvenient and often obfuscates the code, so you end up reinventing c_int/c_long... And that's not ideal either; having the right types [1] always predefined would be much better. On 02/19/12 18:26, Stewart Gordon wrote:If you want to know the size of an int, you would just use int.sizeof. Problem solved.Exactly. Except doing this for D's int would be kind of pointless, wouldn't it?... With a native_int type you *can* write generic code and switch on native_int.sizeof. artur [1] ie a signed/unsigned int that is large as the CPU registers allow. [2] [2] and note that using anything smaller can result in performance degradation, if the values need to be converted to a full-width format.
Feb 19 2012
On 19/02/2012 15:26, Manu wrote: <snip>There is code that assumes size_t is the width of the pointer, and other code that assumes size_t is the width of the native int.<snip> How does it do that? Indeed, how does code rely on the concept of native int at all? Stewart.
Feb 19 2012
On 19 February 2012 18:31, Stewart Gordon <smjg_1998 yahoo.com> wrote:On 19/02/2012 15:26, Manu wrote: <snip>You can't imagine any situation where you might want to know how big an int is? Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... Turn that question around... if you don't know the size of a native int, how do you propose you take advantage of it?There is code that assumes size_t is the width of the pointer, and other code that assumes size_t is the width of the native int.<snip> How does it do that? Indeed, how does code rely on the concept of native int at all?
Feb 19 2012
On 19/02/2012 17:04, Manu wrote: <snip>Indeed, how does code rely on the concept of native int at all? You can't imagine any situation where you might want to know how big an int is?<snip> Hang on ... are we talking here about some "native int", or the int type? If you want to know the size of a "native int", I think you would need to know more about how the particular machine works internally in order to take advantage of it. If you want to know the size of an int, you would just use int.sizeof. Problem solved. Stewart.
Feb 19 2012
On 19 February 2012 19:26, Stewart Gordon <smjg_1998 yahoo.com> wrote:On 19/02/2012 17:04, Manu wrote: <snip>In many cases you wouldn't need to know anything other than that. I don't really understand your resistance? I'm going to have the type when I need it, the question is, will it be standardised, or will I (& everyone else) invent the name and introduce a block of (probably not very portable) version() bullshit at the top of their module? Almost nobody here puts any thought towards portability, or any architecture other than x86+linux. I don't trust individuals writing their own version mess to define it correctly in their libraries... or to do it at all for that matter, they'll just be writing less portable code. Try this: Build phobos for x64, but define size_t as 32bits, and see what happens. You'll see what I'm talking about.Indeed, how does code rely on the concept of native int at all? You can't imagine any situation where you might want to know how big an int is?<snip> Hang on ... are we talking here about some "native int", or the int type? If you want to know the size of a "native int", I think you would need to know more about how the particular machine works internally in order to take advantage of it.
Feb 19 2012
On 19/02/2012 17:51, Manu wrote: <snip>Hang on ... are we talking here about some "native int", or the int type?<snip>I don't really understand your resistance? I'm going to have the type when I need it, the question is, will it be standardised, or will I (& everyone else) invent the name and introduce a block of (probably not very portable) version() bullshit at the top of their module?I'm not saying we shouldn't have native integer types in D. Maybe what's needed is to be clearer on what's meant exactly by a native integer type. And then add the types to Phobos/druntime. I particularly don't understand your suggestion of the names "size_t" and "ssize_t" for these types. They don't seem to me to denote the size of anything. I guess "nativeInt" and "nativeUint", defined in whatever module would be suitable, would be one possibility. Maybe someone has a better idea. But knowing what code in Phobos/druntime should be using native integer types might help put the problem in better perspective. Stewart.
Feb 19 2012
On 19 February 2012 23:16, Stewart Gordon <smjg_1998 yahoo.com> wrote:On 19/02/2012 17:51, Manu wrote: <snip>well ssize_t is an already established compliment to size_t, I guess it's identical to ptrdiff_t, but some CRT's seem to prefer the ssize_t name. Personally size_t and ssize_t make more sense to me than size_t and ptrdiff_t, which seems like a contradiction of terminology, although the 'ptr' name seems more fitting to what it actually is... Ultimately I don't care, I suspect the prior commitment to size_t and ptrdiff_t can not be changed (although redefining their meaning would not be a breaking change, it just might show some cases of inappropriate usages) I agree that nativeInt should probably be in the standard library, but I'm really not into that name. It's really long and ugly. That said, I basically hate size_t too, it doesn't seem very D-ish, reeks of C mischief... and C stuffs up those types so much. It's not dependable what they actually mean in C (ie. ptr size/native word size) on all compilers I've come in contact with :/Hang on ... are we talking here about some "native int", or the int type?<snip> I don't really understand your resistance? I'm going to have the typewhen I need it, the question is, will it be standardised, or will I (& everyone else) invent the name and introduce a block of (probably not very portable) version() bullshit at the top of their module?I'm not saying we shouldn't have native integer types in D. Maybe what's needed is to be clearer on what's meant exactly by a native integer type. And then add the types to Phobos/druntime. I particularly don't understand your suggestion of the names "size_t" and "ssize_t" for these types. They don't seem to me to denote the size of anything. I guess "nativeInt" and "nativeUint", defined in whatever module would be suitable, would be one possibility. Maybe someone has a better idea.But knowing what code in Phobos/druntime should be using native integer types might help put the problem in better perspective. Stewart.
Feb 19 2012
On 2/19/2012 3:15 PM, Manu wrote:Ultimately I don't care, I suspect the prior commitment to size_t and ptrdiff_t can not be changed (although redefining their meaning would not be a breaking change, it just might show some cases of inappropriate usages) I agree that nativeInt should probably be in the standard library, but I'm really not into that name. It's really long and ugly. That said, I basically hate size_t too, it doesn't seem very D-ish, reeks of C mischief... and C stuffs up those types so much. It's not dependable what they actually mean in C (ie. ptr size/native word size) on all compilers I've come in contact with :/I really think that simply adding c_int and c_uint to core.stdc.config will solve the issue. After all, is there any case where the corresponding C int type would be different from a nativeInt?
Feb 19 2012
On 02/20/12 01:48, Walter Bright wrote:On 2/19/2012 3:15 PM, Manu wrote:64bit platforms, depending on the definition of nativeInt. I'm not sure what it should map to, but 'widestInt' seems to be the result asked for in this thread. But would that really be different from c_long? arturUltimately I don't care, I suspect the prior commitment to size_t and ptrdiff_t can not be changed (although redefining their meaning would not be a breaking change, it just might show some cases of inappropriate usages) I agree that nativeInt should probably be in the standard library, but I'm really not into that name. It's really long and ugly. That said, I basically hate size_t too, it doesn't seem very D-ish, reeks of C mischief... and C stuffs up those types so much. It's not dependable what they actually mean in C (ie. ptr size/native word size) on all compilers I've come in contact with :/I really think that simply adding c_int and c_uint to core.stdc.config will solve the issue. After all, is there any case where the corresponding C int type would be different from a nativeInt?
Feb 19 2012
On 20 February 2012 02:48, Walter Bright <newshound2 digitalmars.com> wrote:On 2/19/2012 3:15 PM, Manu wrote:? I must have misunderstood something... I've never seen a 64bit C compiler where 'int' is 64bits.Ultimately I don't care, I suspect the prior commitment to size_t and ptrdiff_t can not be changed (although redefining their meaning would not be a breaking change, it just might show some cases of inappropriate usages) I agree that nativeInt should probably be in the standard library, but I'm really not into that name. It's really long and ugly. That said, I basically hate size_t too, it doesn't seem very D-ish, reeks of C mischief... and C stuffs up those types so much. It's not dependable what they actually mean in C (ie. ptr size/native word size) on all compilers I've come in contact with :/I really think that simply adding c_int and c_uint to core.stdc.config will solve the issue. After all, is there any case where the corresponding C int type would be different from a nativeInt?
Feb 20 2012
On 2/20/2012 3:02 AM, Manu wrote:? I must have misunderstood something... I've never seen a 64bit C compiler where 'int' is 64bits.What are you using in C code for a most efficient integer type?
Feb 20 2012
On 20 February 2012 13:16, Walter Bright <newshound2 digitalmars.com> wrote:On 2/20/2012 3:02 AM, Manu wrote:#ifdef. No 2 C compilers ever seem to agree. It's a major problem in C, hence bringing it up here. Even size_t is often broken in C. I have worked on 64bit systems with 32bit pointers where size_t was still 64bit, but ptrdiff_t was 32bit (I think PS3 is like this, but maybe my memory fails me) I want to be confident when I declare a numeric type that can interact with pointers, and also when I want the native type.? I must have misunderstood something... I've never seen a 64bit C compiler where 'int' is 64bits.What are you using in C code for a most efficient integer type?
Feb 20 2012
On Mon, 20 Feb 2012 11:28:44 -0000, Manu <turkeyman gmail.com> wrote:On 20 February 2012 13:16, Walter Bright <newshound2 digitalmars.com> wrote:I can imagine situations where you want to explicitly have a numeric type that can hold/interact with pointers, or you need /more/ width than the native/efficient int type. But, in /all/ other cases surely we want the **compiler** to pick/use the native/most efficient int type/size. Further, why should we state this explicitly, why shouldn't "int" just /be/ the native/most efficient type (as determined by the compiler during compilation of each/every block of code)... I know, I know, this goes in the face of one of D's initial design decisions - being sure of the width of your types without having to guess or dig in headers for defines etc.. but, remind me why this is a bad idea? Because, it just seems to me that we want "int" to be the native/most efficient type and we want fixed sized types for special/specific cases (like in struct definitions where alignment/size matters, etc), i.e. int a; // native/efficient type int16 b; // 16 bit int int32 c; // 32 bit int int64 d; // 64 bit int ..and so on.. But.. assuming that's not going to change any time soon, we might be able to go the other way. What if we had a built-in "nint" type, which we could use everywhere we didn't care about integer type width, which resulted in the compiler picking the most efficient/native int width on a case by case basis (code inspection, etc.. not sure of the limits of this). Regan -- Using Opera's revolutionary email client: http://www.opera.com/mail/On 2/20/2012 3:02 AM, Manu wrote:#ifdef. No 2 C compilers ever seem to agree. It's a major problem in C, hence bringing it up here. Even size_t is often broken in C. I have worked on 64bit systems with 32bit pointers where size_t was still 64bit, but ptrdiff_t was 32bit (I think PS3 is like this, but maybe my memory fails me) I want to be confident when I declare a numeric type that can interact with pointers, and also when I want the native type.? I must have misunderstood something... I've never seen a 64bit C compiler where 'int' is 64bits.What are you using in C code for a most efficient integer type?
Feb 20 2012
What if te compiler was allowed to optimist to larger types? The only issue is if pulled rely on overflowing. That could be fixed by add in a type with a minimum size specified. This is kind of like C's fast int type. On Feb 20, 2012 8:20 AM, "Regan Heath" <regan netmail.co.nz> wrote:On Mon, 20 Feb 2012 11:28:44 -0000, Manu <turkeyman gmail.com> wrote: On 20 February 2012 13:16, Walter Bright <newshound2 digitalmars.com>wrote: On 2/20/2012 3:02 AM, Manu wrote:I can imagine situations where you want to explicitly have a numeric type that can hold/interact with pointers, or you need /more/ width than the native/efficient int type. But, in /all/ other cases surely we want the **compiler** to pick/use the native/most efficient int type/size. Further, why should we state this explicitly, why shouldn't "int" just /be/ the native/most efficient type (as determined by the compiler during compilation of each/every block of code)... I know, I know, this goes in the face of one of D's initial design decisions - being sure of the width of your types without having to guess or dig in headers for defines etc.. but, remind me why this is a bad idea? Because, it just seems to me that we want "int" to be the native/most efficient type and we want fixed sized types for special/specific cases (like in struct definitions where alignment/size matters, etc), i.e. int a; // native/efficient type int16 b; // 16 bit int int32 c; // 32 bit int int64 d; // 64 bit int ..and so on.. But.. assuming that's not going to change any time soon, we might be able to go the other way. What if we had a built-in "nint" type, which we could use everywhere we didn't care about integer type width, which resulted in the compiler picking the most efficient/native int width on a case by case basis (code inspection, etc.. not sure of the limits of this). Regan -- Using Opera's revolutionary email client: http://www.opera.com/mail/? I must have misunderstood something... I've never seen a 64bit C#ifdef. No 2 C compilers ever seem to agree. It's a major problem in C, hence bringing it up here. Even size_t is often broken in C. I have worked on 64bit systems with 32bit pointers where size_t was still 64bit, but ptrdiff_t was 32bit (I think PS3 is like this, but maybe my memory fails me) I want to be confident when I declare a numeric type that can interact with pointers, and also when I want the native type.compiler where 'int' is 64bits.What are you using in C code for a most efficient integer type?
Feb 20 2012
On 2/20/2012 3:28 AM, Manu wrote:Even size_t is often broken in C. I have worked on 64bit systems with 32bit pointers where size_t was still 64bit, but ptrdiff_t was 32bit (I think PS3 is like this, but maybe my memory fails me)I don't know how that could be considered C standard compliant.I want to be confident when I declare a numeric type that can interact with pointers, and also when I want the native type.I think you're probably best off for now by doing your own alias for it.
Feb 20 2012
On 21 February 2012 12:22, Walter Bright <newshound2 digitalmars.com> wrote:On 2/20/2012 3:28 AM, Manu wrote:I don't know much about what is considered 'standard C', non x86 platforms or the intricacies of native types, so I would like some clarification on the argument going on here. AFAICT, The problem is that size_t is assumed to be the both the size of the pointer and the size of the native int, but sometimes the native int isn't the same as the size of the pointer? So you can have 64bit native ints and 32bit pointers (and maybe even vice-versa)? I also saw reference to register sizes, which I assumed, but am now guessing to be wrong, were the same size as pointers. So the problem seems to be that there are the following things that are all different sizes: * fixed int (32 bit) * native int * pointer * register But some types are conflating them? The argument seems to be confusing me because it jumps rapidly from talking about different processors to different OSes to the C standard. If the only problem is that we need some more types, can't we add them in? I don't see the problem with having verbose, import-only names for things outside the norm, alias them if you want, longer names are better for newcomers. For example, what is ptrdiff_t? I have never seen that before, and the name doesn't help me, from the alias in druntime, it seems to be the type that represents the difference between 2 pointers. Help me out here, what on earth would I use that for? (On a side note to that, no way is ssize_t a good name, ever, forwards and backwards, what on earth is it? super-size_t? here to save you? shady-size_t? you have to make sure it doesn't sell you drugs? size-size_t? it has a stammer?) I also saw a lot of talk about C compilers that don't do the right thing, is that relevant? (I mean that sincerely, not criticism)Even size_t is often broken in C. I have worked on 64bit systems with 32bit pointers where size_t was still 64bit, but ptrdiff_t was 32bit (I think PS3 is like this, but maybe my memory fails me)I don't know how that could be considered C standard compliant.I want to be confident when I declare a numeric type that can interact with pointers, and also when I want the native type.I think you're probably best off for now by doing your own alias for it.
Feb 20 2012
On 02/21/12 04:12, James Miller wrote:If the only problem is that we need some more types, can't we add them in? I don't see the problem with having verbose, import-only names for things outside the norm, alias them if you want, longer names are better for newcomers. For example, what is ptrdiff_t? I have never seen that before, and the name doesn't help me, from the alias in druntime, it seems to be the type that represents the difference between 2 pointers. Help me out here, what on earth would I use that for?In C, for storing the result of (a-b), where a and b are pointers.(On a side note to that, no way is ssize_t a good name, ever, forwards and backwards, what on earth is it? super-size_t? here to save you? shady-size_t? you have to make sure it doesn't sell you drugs? size-size_t? it has a stammer?)It's signed, unlike the unsigned 'size_t'. Types like ptrdiff_t are not necessary in D, because you can write portable code using 'auto' and 'typeof()' - std C didn't have these, so a type had to be invented for everything. D only lacks the 'native' types; while you can, in most cases, find them out using import and version(), the compiler obviously already knows what they are for every supported target. So it's just about exposing them to the compiled code in a std, defined way. The 'C' types are only needed for interoperability, for example - the glib bindings needed these:import core.stdc.limits: c_long, c_ulong; alias int c_int; // Assumes 32-bit wide int. alias uint c_uint; // Assumes 32-bit wide int. import core.sys.posix.sys.types : time_t, ssize_t;IIRC I did not find the C int types conveniently defined anywhere and didn't want to use GCC extensions. ssize_t is std and common enough that it could live outside that sys.posix module. Maybe this is also true for time_t and a few others that weren't needed in this case. artur
Feb 21 2012
On 2/21/2012 1:03 AM, Artur Skawina wrote:Types like ptrdiff_t are not necessary in D, because you can write portable code using 'auto' and 'typeof()' - std C didn't have these, so a type had to be invented for everything.And, in fact, object.di contains: alias typeof(int.sizeof) size_t; alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t;
Feb 21 2012
On 22 February 2012 02:19, Walter Bright <newshound2 digitalmars.com> wrote= :On 2/21/2012 1:03 AM, Artur Skawina wrote:dTypes like ptrdiff_t are not necessary in D, because you can write portable code using 'auto' and 'typeof()' - std C didn't have these, so a type ha=But as far as I can see, size_t and ptrdiff_t have a special meaning inside the compiler, and you can change their alias at will (though I've never tried). --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';to be invented for everything.And, in fact, object.di contains: alias typeof(int.sizeof) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0size_t; alias typeof(cast(void*)0 - cast(void*)0) =A0 ptrdiff_t;
Feb 21 2012
On 21 February 2012 01:22, Walter Bright <newshound2 digitalmars.com> wrote:On 2/20/2012 3:28 AM, Manu wrote:I don't know about you, but I very rarely get to work with a C compiler that is 'standards compliant'.. that concept is kinda like a cruel joke in my experience. Does one even exist? :) I would like to have seen size_t and ptrdiff_t (and friends) also live in core.stdc... and D define and implement its own strictly compliant concepts. As is, any GDC build will have those types defined exactly as in the C compiler... broken or not, and since they're used to interact with C code, it can't be any other way. I want to be confident when I declare a numeric type that can interact withEven size_t is often broken in C. I have worked on 64bit systems with 32bit pointers where size_t was still 64bit, but ptrdiff_t was 32bit (I think PS3 is like this, but maybe my memory fails me)I don't know how that could be considered C standard compliant.Fair enough I guess. Consider it though. I really don't want to rely on core.stdc; that idea makes me feel very uneasy, considering how badly C stuffs all this stuff up. I also don't want to have to import something to access the most basic of types.pointers, and also when I want the native type.I think you're probably best off for now by doing your own alias for it.
Feb 21 2012
On 2/21/2012 12:33 AM, Manu wrote:On 21 February 2012 01:22, Walter Bright <newshound2 digitalmars.com <mailto:newshound2 digitalmars.com>> wrote: On 2/20/2012 3:28 AM, Manu wrote: Even size_t is often broken in C. I have worked on 64bit systems with 32bit pointers where size_t was still 64bit, but ptrdiff_t was 32bit (I think PS3 is like this, but maybe my memory fails me) I don't know how that could be considered C standard compliant. I don't know about you, but I very rarely get to work with a C compiler that is 'standards compliant'.. that concept is kinda like a cruel joke in my experience. Does one even exist? :)The C99 Standard sez: "The types are ptrdiff_t which is the signed integer type of the result of subtracting two pointers; size_t which is the unsigned integer type of the result of the sizeof operator;" I don't know of any excuse for getting this wrong.
Feb 21 2012
On 22/02/2012 02:23, Walter Bright wrote: <snip>The C99 Standard sez: "The types are ptrdiff_t which is the signed integer type of the result of subtracting two pointers; size_t which is the unsigned integer type of the result of the sizeof operator;"And what does it say about what type the sizeof operator returns? Stewart.
Feb 22 2012
On Feb 20, 2012, at 3:16 AM, Walter Bright wrote:On 2/20/2012 3:02 AM, Manu wrote:compiler? I must have misunderstood something... I've never seen a 64bit C =I can't answer for Manu, but I imagine one should probably use = int_fast32_t, etc.=where 'int' is 64bits.=20 What are you using in C code for a most efficient integer type?
Feb 20 2012
On 2012-02-20 12:02, Manu wrote:On 20 February 2012 02:48, Walter Bright <newshound2 digitalmars.com <mailto:newshound2 digitalmars.com>> wrote: On 2/19/2012 3:15 PM, Manu wrote: Ultimately I don't care, I suspect the prior commitment to size_t and ptrdiff_t can not be changed (although redefining their meaning would not be a breaking change, it just might show some cases of inappropriate usages) I agree that nativeInt should probably be in the standard library, but I'm really not into that name. It's really long and ugly. That said, I basically hate size_t too, it doesn't seem very D-ish, reeks of C mischief... and C stuffs up those types so much. It's not dependable what they actually mean in C (ie. ptr size/native word size) on all compilers I've come in contact with :/ I really think that simply adding c_int and c_uint to core.stdc.config will solve the issue. After all, is there any case where the corresponding C int type would be different from a nativeInt? ? I must have misunderstood something... I've never seen a 64bit C compiler where 'int' is 64bits.According to Wikipedia, two out of four 64-bit data models uses 64bit integers, ILP64 and SILP64: -- /Jacob Carlborg
Feb 20 2012
On 02/19/2012 03:59 PM, Manu wrote:Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fit the rest of the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code written using the incorrect types. Some time needs to be taken to correct phobos too I guess.Currently, size_t is defined to be what you call ptr_t, ptrdiff_t is present, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.
Feb 19 2012
On 19 February 2012 20:07, Timon Gehr <timon.gehr gmx.ch> wrote:On 02/19/2012 03:59 PM, Manu wrote:It is just as unportable as size_t its self. The reason you need it is to improve portability, otherwise people need to create arbitrary version mess, which will inevitably be incorrect. Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths. Even just basic efficiency, using 32bit ints on many 64bit machines require extra sign-extend opcodes after every single load... total waste of cpu time. Currently, if you're running a 64bit system with 32bit pointers, there is absolutely nothing that exists at compile time to tell you you're running a 64bit system, or to declare a variable of the machines native type, which you're crazy if you say is not important information. What's the point of a 64bit machine, if you treat it exactly like a 32bit machine in every aspect?Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fit the rest of the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code written using the incorrect types. Some time needs to be taken to correct phobos too I guess.Currently, size_t is defined to be what you call ptr_t, ptrdiff_t is present, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.
Feb 19 2012
On 02/19/2012 07:27 PM, Manu wrote:On 19 February 2012 20:07, Timon Gehr <timon.gehr gmx.ch <mailto:timon.gehr gmx.ch>> wrote: On 02/19/2012 03:59 PM, Manu wrote: Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fit the rest of the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code written using the incorrect types. Some time needs to be taken to correct phobos too I guess. Currently, size_t is defined to be what you call ptr_t, ptrdiff_t is present, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.Note that I agree that getting the terminology straight would be an overall improvement.It is just as unportable as size_t its self.Currently, size_t is typeof(array.length). This is portable, and is basically the only place size_t commonly occurs in D code.The reason you need it is to improve portability, otherwise people need to create arbitrary version mess, which will inevitably be incorrect. Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths.That is not a very valid use case. In every static branch you'll know exactly what the width is.Even just basic efficiency, using 32bit ints on many 64bit machines require extra sign-extend opcodes after every single load... total waste of cpu time.Using 64bit ints everywhere to represent 32bit ints won't make your program go faster. Cache lines fill up faster when the data contains large amounts of unnecessary padding. Furthermore, the compiler should be able to eliminate unneeded sign-extend operations. Anyway, extra sign-extend opcodes are not worth caring about if you get up to twice the number of conflict cache misses.Currently, if you're running a 64bit system with 32bit pointers, there is absolutely nothing that exists at compile time to tell you you're running a 64bit system,Isn't there some version identifier for this? If there is not, such an identifier could be introduced trivially and this must be done.or to declare a variable of the machines native type, which you're crazy if you say is not important information.What do you do with the machine's native type other than checking its size in a static if declaration? If you don't, then the code is unportable, and using the proper fixed size types would make it portable. If you do, then you could have checked a built-in version instead. What you effectively want for optimization is the most efficient type that is at least a certain number of bits wide. And even then, it is a moot point, because storing such variables in memory will add unnecessary padding to your data structures.What's the point of a 64bit machine, if you treat it exactly like a 32bit machine in every aspect?There is none.
Feb 19 2012
On 19 February 2012 21:21, Timon Gehr <timon.gehr gmx.ch> wrote:What about pointer arithmetic? Interaction with C/C++ code? Writing OS level code? Hitting the hardware? And how do you define 'portable' in this context? What makes size_t more portable than a native int? A data structure containing a size_t is not 'portable' in the direct sense...It is just as unportable as size_t its self.Currently, size_t is typeof(array.length). This is portable, and is basically the only place size_t commonly occurs in D code.The reason you need it is to improve portability, otherwise people need toThat's the point. Branches can each implement an efficient path for the different cases.create arbitrary version mess, which will inevitably be incorrect. Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths.That is not a very valid use case. In every static branch you'll know exactly what the width is.Even just basic efficiency, using 32bit ints on many 64bit machinesI'm talking about the stack, passing args etc. Data structures should obviously be as tight as possible.require extra sign-extend opcodes after every single load... total waste of cpu time.Using 64bit ints everywhere to represent 32bit ints won't make your program go faster. Cache lines fill up faster when the data contains large amounts of unnecessary padding. Furthermore, the compiler should be able to eliminate unneeded sign-extend operations. Anyway, extra sign-extend opcodes are not worth caring about if you get up to twice the number of conflict cache misses.Currently, if you're running a 64bit system with 32bit pointers, thereWhy introduce a version identifier, when a type would be so much more useful, and also neater? (usable directly rather than ugly version blocks)is absolutely nothing that exists at compile time to tell you you're running a 64bit system,Isn't there some version identifier for this? If there is not, such an identifier could be introduced trivially and this must be done.or to declare a variable of the machines nativeIf that's all you do with it, then it's already proven its worth. There's a major added bonus that you could USE it... I don't like this argument that it's not portable, it's exactly as portable as size_t is already, and there's no call to remove that.type, which you're crazy if you say is not important information.What do you do with the machine's native type other than checking its size in a static if declaration? If you don't, then the code is unportable, and using the proper fixed size types would make it portable. If you do, then you could have checked a built-in version instead. What you effectively want for optimization is the most efficient type that is at least a certain number of bits wide. And even then, it is a moot point, because storing such variables in memory will add unnecessary padding to your data structures.What's the point of a 64bit machine, if you treat it exactly like a 32bitThen why do so many hardware vendors feel the need to create 64bit chips which are used in 32bit memspace platforms? It's useful to have double width registers. Some algorithms are easier with wider registers, you can move more data faster, it extends your range for intermediate values during calculations, etc. These are still real advantages, even on a 32bit memspace platform.machine in every aspect?There is none.
Feb 19 2012
On 19 February 2012 18:27, Manu <turkeyman gmail.com> wrote:On 19 February 2012 20:07, Timon Gehr <timon.gehr gmx.ch> wrote:gdc offers __builtin_machine_(u)int for word size, and __builtin_pointer_(u)int for pointer size via gcc.builtins module. Nevermind though, it's not quite a "standard" :~) -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';On 02/19/2012 03:59 PM, Manu wrote:It is just as unportable as size_t its self. The reason you need it is to improve portability, otherwise people need to create arbitrary version mess, which will inevitably be incorrect. Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths. Even just basic efficiency, using 32bit ints on many 64bit machines require extra sign-extend opcodes after every single load... total waste of cpu time. Currently, if you're running a 64bit system with 32bit pointers, there is absolutely nothing that exists at compile time to tell you you're running a 64bit system, or to declare a variable of the machines native type, which you're crazy if you say is not important information. What's the point of a 64bit machine, if you treat it exactly like a 32bit machine in every aspect?Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fit the rest of the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code written using the incorrect types. Some time needs to be taken to correct phobos too I guess.Currently, size_t is defined to be what you call ptr_t, ptrdiff_t is present, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.
Feb 20 2012
On 20-02-2012 09:31, Iain Buclaw wrote:On 19 February 2012 18:27, Manu<turkeyman gmail.com> wrote:IMHO, it should be. -- - AlexOn 19 February 2012 20:07, Timon Gehr<timon.gehr gmx.ch> wrote:gdc offers __builtin_machine_(u)int for word size, and __builtin_pointer_(u)int for pointer size via gcc.builtins module. Nevermind though, it's not quite a "standard" :~)On 02/19/2012 03:59 PM, Manu wrote:It is just as unportable as size_t its self. The reason you need it is to improve portability, otherwise people need to create arbitrary version mess, which will inevitably be incorrect. Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths. Even just basic efficiency, using 32bit ints on many 64bit machines require extra sign-extend opcodes after every single load... total waste of cpu time. Currently, if you're running a 64bit system with 32bit pointers, there is absolutely nothing that exists at compile time to tell you you're running a 64bit system, or to declare a variable of the machines native type, which you're crazy if you say is not important information. What's the point of a 64bit machine, if you treat it exactly like a 32bit machine in every aspect?Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fit the rest of the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code written using the incorrect types. Some time needs to be taken to correct phobos too I guess.Currently, size_t is defined to be what you call ptr_t, ptrdiff_t is present, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.
Feb 20 2012
On 20 February 2012 10:31, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 19 February 2012 18:27, Manu <turkeyman gmail.com> wrote:That's beautiful though! Can we alias them, and produce a true D type that represents them? :) My basic issue with these size_t/c_int/core.stdc... stuff, is that it seems the intent is to go out of the way to maintain compatibility with C, at the expense of sucking C's messy and poorly defined types into D, which is a shame. It just results in D having the same crappy archaic typing problems as C. I appreciate that the C types should exist for interoperability with C (ie, their quirks should be preserved for any given compiler/architecture), but I'd also like to see strictly defined types in D with no respect to any C counterpart, guaranteed by the language to be exactly what they claim to be, and not confused depending which compiler you try to use. These 2 GCC intrinsics would appear to be precisely what I was looking for at the start of this thread...On 19 February 2012 20:07, Timon Gehr <timon.gehr gmx.ch> wrote:weOn 02/19/2012 03:59 PM, Manu wrote:Okay, so it came up a couple of times, but the questions is, what arerestgoing to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fit themess,It is just as unportable as size_t its self. The reason you need it is to improve portability, otherwise people need to create arbitrary versionof the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code written using the incorrect types. Some time needs to be taken to correct phobos too I guess.Currently, size_t is defined to be what you call ptr_t, ptrdiff_t is present, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.which will inevitably be incorrect. Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths. Even just basic efficiency, using 32bit ints on many 64bit machinesrequireextra sign-extend opcodes after every single load... total waste of cpu time. Currently, if you're running a 64bit system with 32bit pointers, there is absolutely nothing that exists at compile time to tell you you'rerunning a64bit system, or to declare a variable of the machines native type, which you're crazy if you say is not important information. What's the pointof a64bit machine, if you treat it exactly like a 32bit machine in everyaspect? gdc offers __builtin_machine_(u)int for word size, and __builtin_pointer_(u)int for pointer size via gcc.builtins module. Nevermind though, it's not quite a "standard" :~)
Feb 20 2012
On 20 February 2012 11:14, Manu <turkeyman gmail.com> wrote:On 20 February 2012 10:31, Iain Buclaw <ibuclaw ubuntu.com> wrote:Well, as Walter said, these could be aliased in core.stdc.config. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';On 19 February 2012 18:27, Manu <turkeyman gmail.com> wrote:That's beautiful though! Can we alias them, and produce a true D type that represents them? :) My basic issue with these size_t/c_int/core.stdc... stuff, is that it seems the intent is to go out of the way to maintain compatibility with C, at the expense of sucking C's messy and poorly defined types into D, which is a shame. It just results in D having the same crappy archaic typing problems as C. I appreciate that the C types should exist for interoperability with C (ie, their quirks should be preserved for any given compiler/architecture), but I'd also like to see strictly defined types in D with no respect to any C counterpart, guaranteed by the language to be exactly what they claim to be, and not confused depending which compiler you try to use. These 2 GCC intrinsics would appear to be precisely what I was looking for at the start of this thread...On 19 February 2012 20:07, Timon Gehr <timon.gehr gmx.ch> wrote:gdc offers __builtin_machine_(u)int for word size, and __builtin_pointer_(u)int for pointer size via gcc.builtins module. Nevermind though, it's not quite a "standard" :~)On 02/19/2012 03:59 PM, Manu wrote:It is just as unportable as size_t its self. The reason you need it is to improve portability, otherwise people need to create arbitrary version mess, which will inevitably be incorrect. Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths. Even just basic efficiency, using 32bit ints on many 64bit machines require extra sign-extend opcodes after every single load... total waste of cpu time. Currently, if you're running a 64bit system with 32bit pointers, there is absolutely nothing that exists at compile time to tell you you're running a 64bit system, or to declare a variable of the machines native type, which you're crazy if you say is not important information. What's the point of a 64bit machine, if you treat it exactly like a 32bit machine in every aspect?Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fit the rest of the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code written using the incorrect types. Some time needs to be taken to correct phobos too I guess.Currently, size_t is defined to be what you call ptr_t, ptrdiff_t is present, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.
Feb 20 2012
On 20 February 2012 16:03, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 20 February 2012 11:14, Manu <turkeyman gmail.com> wrote:I don't think they are 'standard c' though ;)On 20 February 2012 10:31, Iain Buclaw <ibuclaw ubuntu.com> wrote:areOn 19 February 2012 18:27, Manu <turkeyman gmail.com> wrote:On 19 February 2012 20:07, Timon Gehr <timon.gehr gmx.ch> wrote:On 02/19/2012 03:59 PM, Manu wrote:Okay, so it came up a couple of times, but the questions is, whatnativewe going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent thechange.integer size. Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fit the rest of the D types, but it's established, so I don't expect it cantheBut we do need the 2 missing types. There is also the problem that there is lots of code written usingtheincorrect types. Some time needs to be taken to correct phobos too I guess.Currently, size_t is defined to be what you call ptr_t, ptrdiff_t is present, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotescopyingregister size? What kind of code requires such a type? It is unportable.It is just as unportable as size_t its self. The reason you need it is to improve portability, otherwise people need to create arbitrary version mess, which will inevitably be incorrect. Anything from calling convention code, structure layout/packing,cpumemory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths. Even just basic efficiency, using 32bit ints on many 64bit machines require extra sign-extend opcodes after every single load... total waste ofthatThat's beautiful though! Can we alias them, and produce a true D typetime. Currently, if you're running a 64bit system with 32bit pointers, there is absolutely nothing that exists at compile time to tell you you're running a 64bit system, or to declare a variable of the machines native type, which you're crazy if you say is not important information. What's the point of a 64bit machine, if you treat it exactly like a 32bit machine in every aspect?gdc offers __builtin_machine_(u)int for word size, and __builtin_pointer_(u)int for pointer size via gcc.builtins module. Nevermind though, it's not quite a "standard" :~)represents them? :) My basic issue with these size_t/c_int/core.stdc... stuff, is that itseemsthe intent is to go out of the way to maintain compatibility with C, attheexpense of sucking C's messy and poorly defined types into D, which is a shame. It just results in D having the same crappy archaic typingproblemsas C. I appreciate that the C types should exist for interoperability with C(ie,their quirks should be preserved for any given compiler/architecture),butI'd also like to see strictly defined types in D with no respect to any C counterpart, guaranteed by the language to be exactly what they claim tobe,and not confused depending which compiler you try to use. These 2 GCC intrinsics would appear to be precisely what I was lookingforat the start of this thread...Well, as Walter said, these could be aliased in core.stdc.config.
Feb 20 2012
On 20 February 2012 16:20, Manu <turkeyman gmail.com> wrote:On 20 February 2012 16:03, Iain Buclaw <ibuclaw ubuntu.com> wrote:OK, I'm just having a trudge through druntime: intptr_t and uintptr_t are guaranteed to match pointer size. https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/stdint.d#cl-70 c_long and c_ulong are guaranteed to match target long size (here would also go c_int and c_uint ;-). https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/config.d#cl-22 This needs fixing, as wchar_t may not be same size across all targets (some change size of wchar_t based on compile time switches). https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/stddef.d#cl-28 This needs fixing, as wint_t may not be same size across all targets. https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/wchar_.d#cl-29 -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';On 20 February 2012 11:14, Manu <turkeyman gmail.com> wrote:I don't think they are 'standard c' though ;)On 20 February 2012 10:31, Iain Buclaw <ibuclaw ubuntu.com> wrote:Well, as Walter said, these could be aliased in core.stdc.config.On 19 February 2012 18:27, Manu <turkeyman gmail.com> wrote:That's beautiful though! Can we alias them, and produce a true D type that represents them? :) My basic issue with these size_t/c_int/core.stdc... stuff, is that it seems the intent is to go out of the way to maintain compatibility with C, at the expense of sucking C's messy and poorly defined types into D, which is a shame. It just results in D having the same crappy archaic typing problems as C. I appreciate that the C types should exist for interoperability with C (ie, their quirks should be preserved for any given compiler/architecture), but I'd also like to see strictly defined types in D with no respect to any C counterpart, guaranteed by the language to be exactly what they claim to be, and not confused depending which compiler you try to use. These 2 GCC intrinsics would appear to be precisely what I was looking for at the start of this thread...On 19 February 2012 20:07, Timon Gehr <timon.gehr gmx.ch> wrote:gdc offers __builtin_machine_(u)int for word size, and __builtin_pointer_(u)int for pointer size via gcc.builtins module. Nevermind though, it's not quite a "standard" :~)On 02/19/2012 03:59 PM, Manu wrote:It is just as unportable as size_t its self. The reason you need it is to improve portability, otherwise people need to create arbitrary version mess, which will inevitably be incorrect. Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths. Even just basic efficiency, using 32bit ints on many 64bit machines require extra sign-extend opcodes after every single load... total waste of cpu time. Currently, if you're running a 64bit system with 32bit pointers, there is absolutely nothing that exists at compile time to tell you you're running a 64bit system, or to declare a variable of the machines native type, which you're crazy if you say is not important information. What's the point of a 64bit machine, if you treat it exactly like a 32bit machine in every aspect?Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fit the rest of the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code written using the incorrect types. Some time needs to be taken to correct phobos too I guess.Currently, size_t is defined to be what you call ptr_t, ptrdiff_t is present, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.
Feb 20 2012
On 20/02/2012 17:21, Iain Buclaw wrote: <snip>c_long and c_ulong are guaranteed to match target long size<snip> Which means what, exactly? Stewart.
Feb 20 2012
Am Mon, 20 Feb 2012 17:26:53 +0000 schrieb Stewart Gordon <smjg_1998 yahoo.com>:On 20/02/2012 17:21, Iain Buclaw wrote: <snip>Exactly what's written there, c_long and c_ulong always match the C long/ulong types, whatever size those may be. It's mostly (only?) useful for C bindings.c_long and c_ulong are guaranteed to match target long size<snip> Which means what, exactly? Stewart.
Feb 20 2012
On 20/02/2012 19:11, Johannes Pfau wrote: <snip>Exactly what's written there, c_long and c_ulong always match the C long/ulong types, whatever size those may be. It's mostly (only?) useful for C bindings.So in other words, it just means whatever somebody has decreed that the "long" keyword in C shall mean on that platform. When did C gain a type called ulong, anyway? Are we going to have c_long_long as well? Stewart.
Feb 21 2012
On 2/21/2012 2:11 PM, Stewart Gordon wrote:When did C gain a type called ulong, anyway?unsigned longAre we going to have c_long_long as well?Probably.
Feb 21 2012
On 2012-02-22 06:24, Walter Bright wrote:On 2/21/2012 2:11 PM, Stewart Gordon wrote:Wouldn't that always be a "long" in D? Or is it the same as with "long" in C. -- /Jacob CarlborgWhen did C gain a type called ulong, anyway?unsigned longAre we going to have c_long_long as well?Probably.
Feb 21 2012
On 22/02/2012 07:24, Jacob Carlborg wrote:On 2012-02-22 06:24, Walter Bright wrote:<snip>On 2/21/2012 2:11 PM, Stewart Gordon wrote:long in D is 64 bits. long in C is 32 bits (on Win16/32 at least). If the C standard sets in stone the size of a long long, then we can do away with a c_long_long and just use long. Otherwise, if we're going to have c_int and c_long, it only makes sense to have c_long_long as well. Stewart.Wouldn't that always be a "long" in D? Or is it the same as with "long" in C.Are we going to have c_long_long as well?Probably.
Feb 22 2012
On 22 February 2012 17:16, Stewart Gordon <smjg_1998 yahoo.com> wrote:On 22/02/2012 07:24, Jacob Carlborg wrote:The C standard is completely irrelevant to D, and should not be considered. The C 'standard' is a guideline at best. I've worked with so many compilers over the years that fail, or ignore the standard in all kinds of ways. Their decisions towards the declaration of these fundamental types is a classic fuck up on lots of compilers. I can't trust anything in D defined to be "what c says".. if it's not defined and guaranteed by D, consider it as not-portable, and you'll probably need to start aliasing your own types inside super-portable libraries; version the hell out of it for every compiler you can find, just like C libs do. (Hello GLint (OpenGL), hkFloat(Havok), DWORD (windows), etc... can you think of a single super-portable library that DOESN'T redefine its primitive types?). As D cross compilers become more and more common, or other D compiler implementations begin to appear, the magnitude of the error will get more and more obvious, and also the longer it's left, the more impossible it will be to change. GDC takes its types from GCC verbatim, and they'll be every bit as broken as they would be in the corresponding C compiler. I just want D to define its types (including pointer (u)int, and native (u)int) explicitly in the D standard, and try and enforce it somehow to the tragedy never appears in D.On 2012-02-22 06:24, Walter Bright wrote:Are we going to have c_long_long as well?On 2/21/2012 2:11 PM, Stewart Gordon wrote:<snip>long in D is 64 bits. long in C is 32 bits (on Win16/32 at least). If the C standard sets in stone the size of a long long, then we can do away with a c_long_long and just use long. Otherwise, if we're going to have c_int and c_long, it only makes sense to have c_long_long as well.Wouldn't that always be a "long" in D? Or is it the same as with "long" in C.Probably.
Feb 22 2012
On 2012-02-20 18:26, Stewart Gordon wrote:On 20/02/2012 17:21, Iain Buclaw wrote: <snip>Simplified: 32bit: Windows long == 32bit Posix long == 32bit 64bit: Windows long == 32bit Posix long == 64bit For a complete table of the 64bit data models see: -- /Jacob Carlborgc_long and c_ulong are guaranteed to match target long size<snip> Which means what, exactly? Stewart.
Feb 20 2012
c_long and c_ulong are guaranteed to match target long size (here would also go c_int and c_uint ;-). https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/config.d#cl-22That is so good! Thanks! Currently, htod translates "unsigned long" to uint, which is wrong in linux 64 bits. Translating to size_t fixes that for linux, but I fear that a C "unsigned long" is not 64bit in all 64bit systems (windows): "About size_t and ptrdiff_t" http://www.codeproject.com/Articles/60082/About-size_t-and-ptrdiff_t Ran into this problem with mysql.h: typedef st_mysql_field { ... unsigned long length; unsigned long max_length; unsigned int name_length; ... } The only adequate fix, is your c_long that matches C's long. This is because uint doesn't change when in 64bit, and size_t fixes it for linux but maybe not for windows. The C standard only guarantees that: sizeof(char) <= sizeof(int) <= sizeof(long) <= sizeof(size_t) Which is insane. At some point in history, a C int meant the native register size for fast integer operations. But now C int seems to have been frozen to 32bits to avoid struct hell. So, in conclusion, my opinion is that there is no sane way of mapping C types to D types but to use something like your c_int, c_uint, c_long, c_ulong. Otherwise, the insanity of non-standard sizes and portability never stops. Love the intptr_t! A REQUEST: how about adding a c_size_t too? --jm
Feb 21 2012
On 21 February 2012 22:45, Juan Manuel Cabo <juanmanuel.cabo gmail.com> wrote:A REQUEST: how about adding a c_size_t too?Eh? -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Feb 21 2012
Eh?All the type sizes vary in broken ways in C. The only sane way to port C structs to D is to use c_<type> that has the size of the C compiler in the target platform. If there is a single C compiler has a different sized size_t than D's, then one has achieved nothing with the c_int, c_long, etc. So that is why it'd be nice, in my opinion, to have c_size_t (and c_ssize_t) if we are going to have c_int, c_long, etc. Sorry for requesting things though!! I still don't know my way around here. --jm On 02/21/2012 08:35 PM, Iain Buclaw wrote:On 21 February 2012 22:45, Juan Manuel Cabo <juanmanuel.cabo gmail.com> wrote:A REQUEST: how about adding a c_size_t too?Eh?
Feb 21 2012
On Feb 21, 2012, at 3:50 PM, Juan Manuel Cabo wrote:size_t is intended to be the C representation. I very much do not want = to end up with a c_size_t. Are there times when D's size_t would be a = different type? Also, I wonder how much code would break if we = eliminated the size_t in object.di and replaced it with Size or = whatever.=Eh?=20 All the type sizes vary in broken ways in C. The only sane way to port C structs to D is to use c_<type> that has the size of the C compiler in the target platform. =20 If there is a single C compiler has a different sized size_t than D's, then one has achieved nothing with the c_int, c_long, etc. =20 So that is why it'd be nice, in my opinion, to have c_size_t (and c_ssize_t) if we are going to have c_int, c_long, etc.
Feb 21 2012
size_t is intended to be the C representation. I very much do not want to end up with a c_size_t.Hahah, hold your jaw because it might drop: Looking for size_t extravagancies in C, I found that VC uses __int64 for size_t in x64 target. So this behaves differently according to the target: size_t s = -2; if (s < -1) { printf("An supposedly unsigned size_t is less than -1 in x64 ??"); } else { printf("all good, size_t is still unsigned"); } Though I don't ever expect to see a VC backend for D, this shows that anything can be expected from C. If you want to keep D's size_t unsigned, then let c_size_t do whatever C does, and let D use sane types that do what the documentation says. :-) --jm On 02/21/2012 09:10 PM, Sean Kelly wrote:On Feb 21, 2012, at 3:50 PM, Juan Manuel Cabo wrote:size_t is intended to be the C representation. I very much do not want to end up with a c_size_t. Are there times when D's size_t would be a different type? Also, I wonder how much code would break if we eliminated the size_t in object.di and replaced it with Size or whatever.Eh?All the type sizes vary in broken ways in C. The only sane way to port C structs to D is to use c_<type> that has the size of the C compiler in the target platform. If there is a single C compiler has a different sized size_t than D's, then one has achieved nothing with the c_int, c_long, etc. So that is why it'd be nice, in my opinion, to have c_size_t (and c_ssize_t) if we are going to have c_int, c_long, etc.
Feb 21 2012
I'm sorry, my snippet is wrong. It's a bit more complicated than what I first thought, and not even uniform between VC versions: "size_t definition and C4267 warning" social.msdn.microsoft.com/forums/en-US/vclanguage/thread/62d6df45-e8e4-4bb2-87e2-b3f8e85b4b37 --jm On 02/21/2012 09:50 PM, Juan Manuel Cabo wrote:size_t is intended to be the C representation. I very much do not want to end up with a c_size_t.Hahah, hold your jaw because it might drop: Looking for size_t extravagancies in C, I found that VC uses __int64 for size_t in x64 target. So this behaves differently according to the target: size_t s = -2; if (s < -1) { printf("An supposedly unsigned size_t is less than -1 in x64 ??"); } else { printf("all good, size_t is still unsigned"); } Though I don't ever expect to see a VC backend for D, this shows that anything can be expected from C. If you want to keep D's size_t unsigned, then let c_size_t do whatever C does, and let D use sane types that do what the documentation says. :-) --jm On 02/21/2012 09:10 PM, Sean Kelly wrote:On Feb 21, 2012, at 3:50 PM, Juan Manuel Cabo wrote:size_t is intended to be the C representation. I very much do not want to end up with a c_size_t. Are there times when D's size_t would be a different type? Also, I wonder how much code would break if we eliminated the size_t in object.di and replaced it with Size or whatever.Eh?All the type sizes vary in broken ways in C. The only sane way to port C structs to D is to use c_<type> that has the size of the C compiler in the target platform. If there is a single C compiler has a different sized size_t than D's, then one has achieved nothing with the c_int, c_long, etc. So that is why it'd be nice, in my opinion, to have c_size_t (and c_ssize_t) if we are going to have c_int, c_long, etc.
Feb 21 2012
On Feb 21, 2012, at 4:50 PM, Juan Manuel Cabo wrote:want to end up with a c_size_t.size_t is intended to be the C representation. I very much do not ==20 Hahah, hold your jaw because it might drop: =20 Looking for size_t extravagancies in C, I found that VC uses __int64 for size_t in x64 target.I think this is actually a good thing, since working with unsigned = integers is a pain. I can't see any system needing that extra bit to = represent size any time soon anyway.=
Feb 21 2012
On 02/21/2012 10:13 PM, Sean Kelly wrote:I think this is actually a good thing, since working with unsigned integers is a pain.Yes, I would prefer that msb bit to be the sign too, but behavior might depend on it, and correctness and predictability is important. My first code snippet was WRONG (sorry for the noise). And I couldn't even reproduce the problem with my VC. A correct snippet is simply this: size_t s = -2; if (s > 0) { printf("unsigned"); } else { printf("signed"); } Also, the shift operator is does a logical or arithmetic shift depending on whether it is signed or unsigned, so the result is different if you do s >> 1 whether s is signed or unsigned. THis is already nitpicky. I'm sorry for the noise. --jm
Feb 21 2012
On 22 February 2012 03:31, Juan Manuel Cabo <juanmanuel.cabo gmail.com>wrote:On 02/21/2012 10:13 PM, Sean Kelly wrote:Actually, it doesn't. It is not defined by C whether it should be arithmetic or logical shift right, and it is up to the compiler to choose. Microsoft's PPC compiler produces a *logical* signed shift right for instance.I think this is actually a good thing, since working with unsignedintegers is a pain. Yes, I would prefer that msb bit to be the sign too, but behavior might depend on it, and correctness and predictability is important. My first code snippet was WRONG (sorry for the noise). And I couldn't even reproduce the problem with my VC. A correct snippet is simply this: size_t s = -2; if (s > 0) { printf("unsigned"); } else { printf("signed"); } Also, the shift operator is does a logical or arithmetic shift depending on whether it is signed or unsigned, so the result is different if you do s >> 1 whether s is signed or unsigned.
Feb 22 2012
On 2/21/2012 4:50 PM, Juan Manuel Cabo wrote:Looking for size_t extravagancies in C, I found that VC uses __int64 for size_t in x64 target.Which is correct. size_t for 64 bit D is also a 64 bit integral type.
Feb 21 2012
On Tuesday, February 21, 2012 21:22:54 Walter Bright wrote:On 2/21/2012 4:50 PM, Juan Manuel Cabo wrote:Yes, but __int64 is a signed integeral type, whereas size_t in D is an unsigned integeral type. - Jonathan M DavisLooking for size_t extravagancies in C, I found that VC uses __int64 for size_t in x64 target.Which is correct. size_t for 64 bit D is also a 64 bit integral type.
Feb 21 2012
On 2/21/2012 9:56 PM, Jonathan M Davis wrote:On Tuesday, February 21, 2012 21:22:54 Walter Bright wrote:Ah, I see.On 2/21/2012 4:50 PM, Juan Manuel Cabo wrote:Yes, but __int64 is a signed integeral type, whereas size_t in D is an unsigned integeral type.Looking for size_t extravagancies in C, I found that VC uses __int64 for size_t in x64 target.Which is correct. size_t for 64 bit D is also a 64 bit integral type.
Feb 21 2012
On 21/02/2012 22:45, Juan Manuel Cabo wrote: <snip>The C standard only guarantees that: sizeof(char)<= sizeof(int)<= sizeof(long)<= sizeof(size_t)<snip> I'm surprised. I'd assumed that, under 16-bit DOS/Windows, a size_t would be 16 bits. But no. Could memory blocks 64K or larger actually be allocated under those systems? Stewart.
Feb 21 2012
I just went to see a standard draft (http://www.clc-wiki.net/wiki/the_C_Standard) to make sure, and it is even more convoluted than just that, but essentially the same. Basically it says that chars must be at least 8bits and that shorts and ints must be able to represent at least 16 bits. Then the ranks of the types are related to each other like that: rank(_Bool) < rank(char) < rank(short) < rank(int) < rank(long int) < rank(long long int) but rank is about conversion, not size, so while rank is strictly ordered, sizeof types might not. I didn't find size_t other than as the type of the value of sizeof() expressions. So, size_t is just standardized as the type of (sizeof(anystuff)). I saw sizeof(long) <= sizeof(size_t) in a website, but not on the standard. So the standard doesn't even guarantee size_t being more than other types, or the bigger type. --jm On 02/21/2012 10:23 PM, Stewart Gordon wrote:On 21/02/2012 22:45, Juan Manuel Cabo wrote: <snip>The C standard only guarantees that: sizeof(char)<= sizeof(int)<= sizeof(long)<= sizeof(size_t)<snip> I'm surprised. I'd assumed that, under 16-bit DOS/Windows, a size_t would be 16 bits. But no. Could memory blocks 64K or larger actually be allocated under those systems? Stewart.
Feb 21 2012
size_t being the typeof sizeof() expressions, tell you the upper bound for the size of static arrays, statically allocated: sizeof(buffer)/sizeof(int) has to be representable in a size_t. It tells you nothing else. What you can allocate dinamically depends on the architecture and how it lets you address it. 16bit intel had 16bit segments and offsets, so memory was segmented and you couldn't address more than 64kb at a time. So you couldn't have grabbed^H^H"allocated" more than 64kb in real mode in intel in a single linear block. --jmI'm surprised. I'd assumed that, under 16-bit DOS/Windows, a size_t would be 16 bits. But no. Could memory blocks 64K or larger actually be allocated under those systems?
Feb 21 2012
On 2/21/2012 6:07 PM, Juan Manuel Cabo wrote:16bit intel had 16bit segments and offsets, so memory was segmented and you couldn't address more than 64kb at a time. So you couldn't have grabbed^H^H"allocated" more than 64kb in real mode in intel in a single linear block.size_t was 16 bits on all 16 bit memory models except the 'huge' one.
Feb 21 2012
On 22/02/12 06:16, Walter Bright wrote:On 2/21/2012 6:07 PM, Juan Manuel Cabo wrote:I expected that for ptrdiff_t, but for size_t as well? So sizeof(int *) was larger than size_t ?16bit intel had 16bit segments and offsets, so memory was segmented and you couldn't address more than 64kb at a time. So you couldn't have grabbed^H^H"allocated" more than 64kb in real mode in intel in a single linear block.size_t was 16 bits on all 16 bit memory models except the 'huge' one.
Feb 22 2012
On 22 February 2012 17:39, Don Clugston <dac nospam.com> wrote:On 22/02/12 06:16, Walter Bright wrote:I've worked on platforms where sizeof(void*) was smaller than sizeof(size_t)On 2/21/2012 6:07 PM, Juan Manuel Cabo wrote:I expected that for ptrdiff_t, but for size_t as well? So sizeof(int *) was larger than size_t ?16bit intel had 16bit segments and offsets, so memory was segmented and you couldn't address more than 64kb at a time. So you couldn't have grabbed^H^H"allocated" more than 64kb in real mode in intel in a single linear block.size_t was 16 bits on all 16 bit memory models except the 'huge' one.
Feb 22 2012
On 20 February 2012 19:21, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 20 February 2012 16:20, Manu <turkeyman gmail.com> wrote:It seems the problem is already MUCH worse than in D already :( .. this was precisely my fear. Why all these redundant aliases? Just for C compatibility? Exactly one identifier for each concept should be nominated and promoted as 'standard' in D, and everyone use that same thing... The myriad of aliases may still be useful for extern(C) I suppose, but I think this is a major problem that needs careful consideration. I think one of the most insidious side effects of this problem is that programmers don't fully understand what each type is meant to represent exactly, and they accidentally select the wrong one that just appears to do the job correctly on their machine/platform at that particular moment. I'm sure this is the reason behind C compilers messing up the definition of these themselves types so frequently.On 20 February 2012 16:03, Iain Buclaw <ibuclaw ubuntu.com> wrote:alsoOn 20 February 2012 11:14, Manu <turkeyman gmail.com> wrote:On 20 February 2012 10:31, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 19 February 2012 18:27, Manu <turkeyman gmail.com> wrote:On 19 February 2012 20:07, Timon Gehr <timon.gehr gmx.ch> wrote:On 02/19/2012 03:59 PM, Manu wrote:Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t shouldtheexist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fitusingrest of the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code writtentoothe incorrect types. Some time needs to be taken to correct phobosisI guess.Currently, size_t is defined to be what you call ptr_t, ptrdiff_teverypresent, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.It is just as unportable as size_t its self. The reason you need it is to improve portability, otherwise people need to create arbitrary version mess, which will inevitably be incorrect. Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths. Even just basic efficiency, using 32bit ints on many 64bit machines require extra sign-extend opcodes after every single load... total waste of cpu time. Currently, if you're running a 64bit system with 32bit pointers, there is absolutely nothing that exists at compile time to tell you you're running a 64bit system, or to declare a variable of the machines native type, which you're crazy if you say is not important information. What's the point of a 64bit machine, if you treat it exactly like a 32bit machine inatThat's beautiful though! Can we alias them, and produce a true D type that represents them? :) My basic issue with these size_t/c_int/core.stdc... stuff, is that it seems the intent is to go out of the way to maintain compatibility with C,aspect?gdc offers __builtin_machine_(u)int for word size, and __builtin_pointer_(u)int for pointer size via gcc.builtins module. Nevermind though, it's not quite a "standard" :~)is athe expense of sucking C's messy and poorly defined types into D, whichanyshame. It just results in D having the same crappy archaic typing problems as C. I appreciate that the C types should exist for interoperability with C (ie, their quirks should be preserved for any given compiler/architecture), but I'd also like to see strictly defined types in D with no respect totoC counterpart, guaranteed by the language to be exactly what they claimOK, I'm just having a trudge through druntime: intptr_t and uintptr_t are guaranteed to match pointer size. https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/stdint.d#cl-70 c_long and c_ulong are guaranteed to match target long size (here would also go c_int and c_uint ;-). https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/config.d#cl-22 This needs fixing, as wchar_t may not be same size across all targets (some change size of wchar_t based on compile time switches). https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/stddef.d#cl-28 This needs fixing, as wint_t may not be same size across all targets. https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/wchar_.d#cl-29 -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';I don't think they are 'standard c' though ;)be, and not confused depending which compiler you try to use. These 2 GCC intrinsics would appear to be precisely what I was looking for at the start of this thread...Well, as Walter said, these could be aliased in core.stdc.config.
Feb 20 2012
Am Mon, 20 Feb 2012 21:43:31 +0200 schrieb Manu <turkeyman gmail.com>:On 20 February 2012 19:21, Iain Buclaw <ibuclaw ubuntu.com> wrote:That's exactly what those types are for and that's the reason they're in core.stdc.* . Maybe those types shouldn't be used in normal D code, but they are necessary for C bindings.On 20 February 2012 16:20, Manu <turkeyman gmail.com> wrote:It seems the problem is already MUCH worse than in D already :( .. this was precisely my fear. Why all these redundant aliases? Just for C compatibility?On 20 February 2012 16:03, Iain Buclaw <ibuclaw ubuntu.com> wrote:alsoOn 20 February 2012 11:14, Manu <turkeyman gmail.com> wrote:On 20 February 2012 10:31, Iain Buclaw <ibuclaw ubuntu.com> wrote:On 19 February 2012 18:27, Manu <turkeyman gmail.com> wrote:On 19 February 2012 20:07, Timon Gehr <timon.gehr gmx.ch> wrote:On 02/19/2012 03:59 PM, Manu wrote:Okay, so it came up a couple of times, but the questions is, what are we going to do about it? size_t and ptrdiff_t are incomplete, and represent non-complimentary signed/unsigned halves of the requirement. There are TWO types needed, register size, and pointer size. Currently, these are assumed to be the same, which is a false assumption. I propose size_t + ssize_t should both exist, and represent the native integer size. Also something like ptr_t, and ptrdiff_t shouldtheexist, and represent the size of the pointer. Personally, I don't like the _t notation at all. It doesn't fitusingrest of the D types, but it's established, so I don't expect it can change. But we do need the 2 missing types. There is also the problem that there is lots of code writtentoothe incorrect types. Some time needs to be taken to correct phobosisI guess.Currently, size_t is defined to be what you call ptr_t, ptrdiff_teverypresent, and what you call size_t/ssize_t does not exist. Under which circumstances is it important to have a distinct type that denotes the register size? What kind of code requires such a type? It is unportable.It is just as unportable as size_t its self. The reason you need it is to improve portability, otherwise people need to create arbitrary version mess, which will inevitably be incorrect. Anything from calling convention code, structure layout/packing, copying memory, basically optimising for 64bits at all... I can imagine static branches on the width of that type to select different paths. Even just basic efficiency, using 32bit ints on many 64bit machines require extra sign-extend opcodes after every single load... total waste of cpu time. Currently, if you're running a 64bit system with 32bit pointers, there is absolutely nothing that exists at compile time to tell you you're running a 64bit system, or to declare a variable of the machines native type, which you're crazy if you say is not important information. What's the point of a 64bit machine, if you treat it exactly like a 32bit machine inatThat's beautiful though! Can we alias them, and produce a true D type that represents them? :) My basic issue with these size_t/c_int/core.stdc... stuff, is that it seems the intent is to go out of the way to maintain compatibility with C,aspect?gdc offers __builtin_machine_(u)int for word size, and __builtin_pointer_(u)int for pointer size via gcc.builtins module. Nevermind though, it's not quite a "standard" :~)is athe expense of sucking C's messy and poorly defined types into D, whichanyshame. It just results in D having the same crappy archaic typing problems as C. I appreciate that the C types should exist for interoperability with C (ie, their quirks should be preserved for any given compiler/architecture), but I'd also like to see strictly defined types in D with no respect totoC counterpart, guaranteed by the language to be exactly what they claimOK, I'm just having a trudge through druntime: intptr_t and uintptr_t are guaranteed to match pointer size. https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/stdint.d#cl-70 c_long and c_ulong are guaranteed to match target long size (here would also go c_int and c_uint ;-). https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/config.d#cl-22 This needs fixing, as wchar_t may not be same size across all targets (some change size of wchar_t based on compile time switches). https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/stddef.d#cl-28 This needs fixing, as wint_t may not be same size across all targets. https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/wchar_.d#cl-29 -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';I don't think they are 'standard c' though ;)be, and not confused depending which compiler you try to use. These 2 GCC intrinsics would appear to be precisely what I was looking for at the start of this thread...Well, as Walter said, these could be aliased in core.stdc.config.
Feb 20 2012
On Feb 20, 2012, at 11:43 AM, Manu wrote:On 20 February 2012 19:21, Iain Buclaw <ibuclaw ubuntu.com> wrote: =20 OK, I'm just having a trudge through druntime: =20 intptr_t and uintptr_t are guaranteed to match pointer size. =https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/st= dint.d#cl-70=20 c_long and c_ulong are guaranteed to match target long size (here would also go c_int and c_uint ;-). =https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/co= nfig.d#cl-22=20 This needs fixing, as wchar_t may not be same size across all targets (some change size of wchar_t based on compile time switches). =https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/st= ddef.d#cl-28=20 This needs fixing, as wint_t may not be same size across all targets. =https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/wc= har_.d#cl-29=20 -- Iain Buclaw =20 *(p < e ? p++ : p) =3D (c & 0x0f) + '0'; =20 It seems the problem is already MUCH worse than in D already :( .. =this was precisely my fear.Why all these redundant aliases? Just for C compatibility?core.stdc is an interface to the C99 API, so everything is preserved = verbatim. c_long and c_ulong were added because the size of C long = differs between Windows and non-Windows x86_64 platforms. Typically, = int, short, etc are the same however, which is why there's currently no = c_int--it was just a needless complication at the time. The aliases for = D users, if the exist at all, should be separate.=
Feb 20 2012
On 20 February 2012 21:51, Sean Kelly <sean invisibleduck.org> wrote:On Feb 20, 2012, at 11:43 AM, Manu wrote:What about intptr_t/uintptr_t, are they builtins, or in core.stdc?On 20 February 2012 19:21, Iain Buclaw <ibuclaw ubuntu.com> wrote: OK, I'm just having a trudge through druntime: intptr_t and uintptr_t are guaranteed to match pointer size.https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/stdint.d#cl-70c_long and c_ulong are guaranteed to match target long size (here would also go c_int and c_uint ;-).https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/config.d#cl-22This needs fixing, as wchar_t may not be same size across all targets (some change size of wchar_t based on compile time switches).https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/stddef.d#cl-28This needs fixing, as wint_t may not be same size across all targets.https://bitbucket.org/goshawk/gdc/src/87241c8e754b/d/druntime/core/stdc/wchar_.d#cl-29-- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; It seems the problem is already MUCH worse than in D already :( .. thiswas precisely my fear.Why all these redundant aliases? Just for C compatibility?core.stdc is an interface to the C99 API, so everything is preserved verbatim. c_long and c_ulong were added because the size of C long differs between Windows and non-Windows x86_64 platforms. Typically, int, short, etc are the same however, which is why there's currently no c_int--it was just a needless complication at the time. The aliases for D users, if the exist at all, should be separate.
Feb 20 2012
On Feb 20, 2012, at 2:34 PM, Manu wrote:=20 What about intptr_t/uintptr_t, are they builtins, or in core.stdc?core.stdc. The only aliases that currently exist are defined in = object.di: alias typeof(int.sizeof) size_t; alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t; alias ptrdiff_t sizediff_t; We probably need to add ssize_t at some point. Not sure about anything = more than that.=
Feb 20 2012
Manu <turkeyman gmail.com> wrote:I propose size_t + ssize_t should both exist, and represent the native integer size.sizediff_t (currently just aliased to ptrdiff_t but the link could be broken).Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer.core.stdc.stdint.uintptr_t
Feb 19 2012
On 20 February 2012 01:10, kennytm <kennytm gmail.com> wrote:Manu <turkeyman gmail.com> wrote:O_o .. how is this different to size_t now? Why the redundant alias?I propose size_t + ssize_t should both exist, and represent the native integer size.sizediff_t (currently just aliased to ptrdiff_t but the link could be broken).Also something like ptr_t, and ptrdiff_t should also exist, and represent the size of the pointer.core.stdc.stdint.uintptr_t
Feb 19 2012
On 02/20/12 00:17, Manu wrote:On 20 February 2012 01:10, kennytm <kennytm gmail.com <mailto:kennytm gmail.com>> wrote: Manu <turkeyman gmail.com <mailto:turkeyman gmail.com>> wrote: > I propose size_t + ssize_t should both exist, and represent the native > integer size. sizediff_t (currently just aliased to ptrdiff_t but the link could be broken). > Also something like ptr_t, and ptrdiff_t should also exist, > and represent the size of the pointer. > core.stdc.stdint.uintptr_t O_o .. how is this different to size_t now? Why the redundant alias?C compatibility? It is redundant in D, at least until it supports non-flat address spaces. :^) uintptr_t can hold a pointer, size_t only the size of something. These days there's usually not much difference, but take eg x86_16 segments - you can have several 'views' into memory, that allow for <= size_t-sized objects, but a full 'address' of such an object won't fit into a size_t. artur
Feb 19 2012
On 19/02/2012 23:47, Artur Skawina wrote:On 02/20/12 00:17, Manu wrote:<snip>Why would you want to use meaningless type aliases defined in the C headers in D code?core.stdc.stdint.uintptr_t O_o .. how is this different to size_t now? Why the redundant alias?C compatibility?It is redundant in D, at least until it supports non-flat address spaces. :^) uintptr_t can hold a pointer,<snip> Why would you want to do that, as opposed to use one of the pointer types (which is indeed required for GC to work correctly)? Stewart.
Feb 19 2012
On 02/20/12 04:21, Stewart Gordon wrote:On 19/02/2012 23:47, Artur Skawina wrote:C compatibility?On 02/20/12 00:17, Manu wrote:<snip>Why would you want to use meaningless type aliases defined in the C headers in D code?core.stdc.stdint.uintptr_t O_o .. how is this different to size_t now? Why the redundant alias?C compatibility?That's how it can be used in *C*. And the reason it needs to be exposed to D code is for interoperability with C. arturuintptr_t can hold a pointer,<snip> Why would you want to do that, as opposed to use one of the pointer types (which is indeed required for GC to work correctly)?
Feb 19 2012
On 20/02/2012 03:44, Artur Skawina wrote: <snip>IINM, C calling conventions care only about the size of a type, not the name or intrinsic nature of it. Therefore this is a non-issue. Stewart.Why would you want to do that, as opposed to use one of the pointer types (which is indeed required for GC to work correctly)?That's how it can be used in *C*. And the reason it needs to be exposed to D code is for interoperability with C.
Feb 20 2012
On 20 February 2012 20:07, Artur Skawina <art.08.09 gmail.com> wrote:On 02/20/12 13:32, Stewart Gordon wrote:No, this would be very very bad. People would use 'int' out of habit in data structures, and mess up binary compatibility and alignment rules. I personally quite like D's int types as they are, but note there are some 'missing' (well, not missing, as we're discussing, but they are not well defined, or named, and needlessly aliased)On 20/02/2012 03:44, Artur Skawina wrote: <snip>types (which isWhy would you want to do that, as opposed to use one of the pointerwith C.indeed required for GC to work correctly)?That's how it can be used in *C*. And the reason it needs to be exposed to D code is for interoperabilityIINM, C calling conventions care only about the size of a type, not thename or intrinsic nature of it. Therefore this is a non-issue. struct S { uintptr_t a; }; extern (C) uintptr_t f(S* s, uintptr_t* blah); "uintptr_t" is not the best example here (because it will rarely appear in C APIs), but still shows the problem - you need to know what it is - otherwise you're left with guessing and eg assuming that uintptr==size_t. Fixing historical mistakes can be hard. There are basically three types of integer types: a) known fixed size types, such as a 32-bit wide unsigned int b) types, that are not explicitly sized, but meet certain criteria, eg: sizeof(short)<=sizeof(int)<=sizeof(long) c) externally defined types, which must always have the same representation, the above uintptr_t example falls into this category. 'C' didn't have the (a) types, so everybody had to redefine u8/s16/u32/s64 etc. 'D' added these as builtin types so that problem was solved. Unfortunately, instead of eg using the de facto std s16/s32/s64, D reused short/int/long. 'C's short/int/long were poorly (too loosely) defined, but what should have been done is defining them in 'D' as, for example: int: efficient integer type, fitting in a CPU register and at least 32 bit wide;long: efficient integer type, fitting in a CPU register and as wide as a GPR.I don't think the term 'long' here, as opposed to 'int' draws this distinction... so I really can't buy into this logic.Fixing things up now, with for example "nativeInt" (maps to "int" above) and "widestInt" (the "long" above), is not easy. They are needed, that's why threads like this one appear, but simply adding them to the language or std library [1] wouldn't be enough. Why? Think literals, promotion and auto -- I'm afraid programmers working with 'native' ints may not be expecting expressions evaluating to a narrower type. So there probably is no ideal simple solution for D2. For 64-bit platforms and a future D3 language, the int/long, as defined above, would be a mostly backward compatible change.I prefer to explicitly identify these types personally. Predictable sized types are better to have people punching away with no real consideration to the specific use case. People should only use these resizing types deliberately when they know what they're doing.artur [1] fundamental types like these should not require any imports, so object.d and/or compiler is the best place for them.
Feb 20 2012
On 02/20/12 20:50, Manu wrote:On 20 February 2012 20:07, Artur Skawina <art.08.09 gmail.com <mailto:art.08.09 gmail.com>> wrote: On 02/20/12 13:32, Stewart Gordon wrote: > On 20/02/2012 03:44, Artur Skawina wrote: > <snip> >>> Why would you want to do that, as opposed to use one of the pointer types (which is >>> indeed required for GC to work correctly)? >> >> That's how it can be used in *C*. >> >> And the reason it needs to be exposed to D code is for interoperability with C. > > IINM, C calling conventions care only about the size of a type, not the name or intrinsic nature of it. Therefore this is a non-issue. struct S { uintptr_t a; }; extern (C) uintptr_t f(S* s, uintptr_t* blah); "uintptr_t" is not the best example here (because it will rarely appear in C APIs), but still shows the problem - you need to know what it is - otherwise you're left with guessing and eg assuming that uintptr==size_t. Fixing historical mistakes can be hard. There are basically three types of integer types: a) known fixed size types, such as a 32-bit wide unsigned int b) types, that are not explicitly sized, but meet certain criteria, eg: sizeof(short)<=sizeof(int)<=sizeof(long) c) externally defined types, which must always have the same representation, the above uintptr_t example falls into this category. 'C' didn't have the (a) types, so everybody had to redefine u8/s16/u32/s64 etc. 'D' added these as builtin types so that problem was solved. Unfortunately, instead of eg using the de facto std s16/s32/s64, D reused short/int/long. 'C's short/int/long were poorly (too loosely) defined, but what should have been done is defining them in 'D' as, for example: int: efficient integer type, fitting in a CPU register and at least 32 bit wide; No, this would be very very bad. People would use 'int' out of habit in data structures, and mess up binary compatibility and alignment rules.Explicitly sized types (ie u32 and friends) is what should be used by default in any externally visible data structures. Yes, D's attempt at redefining int and long as fixed-size integers will cause confusion. But note that the compiler could help here, by disallowing any use of int and long in aggregates not marked with an 'internal' attribute. So a relatively safe migration path might be possible.I personally quite like D's int types as they are, but note there are some 'missing' (well, not missing, as we're discussing, but they are not well defined, or named, and needlessly aliased) long: efficient integer type, fitting in a CPU register and as wide as a GPR. I don't think the term 'long' here, as opposed to 'int' draws this distinction... so I really can't buy into this logic. Fixing things up now, with for example "nativeInt" (maps to "int" above) and "widestInt" (the "long" above), is not easy. They are needed, that's why threads like this one appear, but simply adding them to the language or std library [1] wouldn't be enough. Why? Think literals, promotion and auto -- I'm afraid programmers working with 'native' ints may not be expecting expressions evaluating to a narrower type. So there probably is no ideal simple solution for D2. For 64-bit platforms and a future D3 language, the int/long, as defined above, would be a mostly backward compatible change. I prefer to explicitly identify these types personally. Predictable sized types are better to have people punching away with no real consideration to the specific use case. People should only use these resizing types deliberately when they know what they're doing.I'd like to avoid using these long-named 'nativeInt' types when I know what I'm doing... ;) But, other than the 'int' and 'long' names, would such two types be enough? For D2 I'll probably end up aliasing them to something like rint/urint and wint/uwint anyway; short-term the question is only how to reliably find the alias source. artur
Feb 20 2012