Re: [Boost-users] size_type doubts / integer library..

-----Ursprüngliche Nachricht----- On Mon, Aug 18, 2008 at 12:06:08PM +0200, Lang Stefan wrote:
A) you intend to use your ID to later reference some address or offset (which is the same) in memory. If that is your intention, then you should stick to the size type (i. e. std:size_t). Problem solved.
Yes, it is used as an index into a vector. And that's what I did (typedef vector<..>::size_type pin_id).
Well, then why don't you simply use std::size_t ? Yes, it's unsigned, and I agree with you it's not perfect (see below). But it will immediately rid you of all those nasty conversion warnings!
Hm, do they? Correct me if I'm wrong, but I don't think that C++ mandates flat address space -- it just requires that each individual object has a contiguous memory representation. And there can be discrepancy between the two, e.g. 80286 protected mode: largest segment size is 64k, yet the largest amount of addressable memory is 16MB (or even in the range of TB if one allocates all LDTs and plays with swapping).
Bugger, you're right, didn't think of that.
So, size_type should be able to represent the size of a *single* largest representable object. Why use it for e.g. number of elements in a vector?
That is something I did give some thought about in the past, to the point where I considered implementing my own set of container classes! However, I realized that in a sense, 'size_type' is indeed the correct type for an index. The reason behind it is this: an index type needs to be able to address a range of values that spans the minimum (0) and maximum (?) possible index for a container of some arbitrary type. For the STL, the smallest entity you can put inside a container is a single byte (disregarding bit-arrays). And the maximum number of such entities a container could legally contain would be limited by the amount of memory available divided by the size of the contained elements. While, as you pointed out, there doesn't need to be a direct relation from index to memory address, the range an index type needs to cover is equal to the range a 'size_type' needs to cover. Moreover, at least on a small scope, every architecture I am aware of groups values of container elements into one or more chunks of memory, which in turn store adjacent values into adjacent memory slots. So at least on a local scale, index values do correspond to memory addresses or memory offsets.
The "problem" could be solved by using largest _signed_ type both for size_type and difference_type. [snip] So I'd advocate signed representation for size_type and difference_type.
I agree. Stefan

So at least on a local scale, index values do correspond to memory addresses or memory offsets.
Sure, A part from STL and other containers using they own operator, when you use direct memory access a index is used to access the flat memory of the allocated object/array.
The "problem" could be solved by using largest _signed_ type both for size_type and difference_type. [snip] So I'd advocate signed representation for size_type and difference_type.
Sure, also because when you play with pointers you have negative indexes too. So a signed index is welcome, and it should cover the range of the maximum memory size of an object (not the entire memory). But on a 32 bit architecture where theorically I can allocate up to 4 Gigabyte for a single object using a signed integer requires a 32bit + sign = 33 bits. Ops... what now? A) using signed 32bit, so the memory address swaps between -2^31 and +2^31-1. Not exactly elegant. B) using unsigned 32 bit, a contingous address from 0 to +2^32. C) using a bigger integral signed type, probably a 64 bit signed. And 2 GByte is not that uncommon...

2008/8/18 Andrea Denzler
So at least on a local scale, index values do correspond to memory addresses or memory offsets.
Sure, A part from STL and other containers using they own operator, when you use direct memory access a index is used to access the flat memory of the allocated object/array.
The "problem" could be solved by using largest _signed_ type both for size_type and difference_type. [snip] So I'd advocate signed representation for size_type and difference_type.
Sure, also because when you play with pointers you have negative indexes too. So a signed index is welcome, and it should cover the range of the maximum memory size of an object (not the entire memory).
But on a 32 bit architecture where theorically I can allocate up to 4 Gigabyte for a single object using a signed integer requires a 32bit + sign = 33 bits. Ops... what now? A) using signed 32bit, so the memory address swaps between -2^31 and +2^31-1. Not exactly elegant. B) using unsigned 32 bit, a contingous address from 0 to +2^32. C) using a bigger integral signed type, probably a 64 bit signed. And 2 GByte is not that uncommon...
I believe (I checked some time ago) that you cannot allocate an object of size 2GB on any 32-bit OS that I could get my hands on. Do you know of any place where you can? Chris

-----Messaggio originale----- I believe (I checked some time ago) that you cannot allocate an object of size 2GB on any 32-bit OS that I could get my hands on. Do you know of any place where you can?
Sure those systems are few, very few, but they exist. I think Solaris/x86 can go to nearly 4GByte, some Linux to 3 GByte, and why not talking about the old 80286 allowing 64Kbyte allocations on a 16bit addressing scheme.

2008/8/18 Andrea Denzler
-----Messaggio originale----- I believe (I checked some time ago) that you cannot allocate an object of size 2GB on any 32-bit OS that I could get my hands on. Do you know of any place where you can?
Sure those systems are few, very few, but they exist. I think Solaris/x86 can go to nearly 4GByte, some Linux to 3 GByte, and why not talking about the old 80286 allowing 64Kbyte allocations on a 16bit addressing scheme.
While Linux applications can allocate up to 3 GB altogether, I've never seen a system where any single malloc request over about 800MB works. Chris

On Tue, Aug 19, 2008 at 12:02:26AM +0200, Andrea Denzler wrote:
-----Messaggio originale----- I believe (I checked some time ago) that you cannot allocate an object of size 2GB on any 32-bit OS that I could get my hands on. Do you know of any place where you can?
Sure those systems are few, very few, but they exist. I think Solaris/x86 can go to nearly 4GByte, some Linux to 3 GByte, and why not talking about the old 80286 allowing 64Kbyte allocations on a 16bit addressing scheme.
You are talking about the size of address space available to the user program. Even if your address space is 3GB, it's improbable that you're going to be able to allocate huge chunks due to external fragmentation of the address space, esp. when randomization (ASLR) is in effect.

Sure those systems are few, very few, but they exist. I think Solaris/x86 can go to nearly 4GByte, some Linux to 3 GByte, and why not talking about the old 80286 allowing 64Kbyte allocations on a 16bit addressing scheme. You are talking about the size of address space available to the user
-----Messaggio originale----- program. Even if your address space is 3GB, it's improbable that you're going to be able to allocate huge chunks due to external fragmentation of the address space, esp. when randomization (ASLR) is in effect.
It's not common but also not impossible, actually I do allocate single big chunks (well over 1 GB). Maybe in 5 years we still work with 32 bit code but running on computers where 16 GB is common so addressing up to 4GB is not that impossible. But sure, it's more an exception than a real situation.
participants (4)
-
Andrea Denzler
-
Chris Jefferson
-
Lang Stefan
-
Zeljko Vrba