Settling ideas

G

Gonçalo Rodrigues

Hi all, once again

Thanks to those who replied to my earlier post "2 questions on
primitive types". I have been reading the FAQ and the the dinkum C++
library, so let me make a few more questions so that I can settle
these things on my head.

1. 'int' is the natural signed integral type for a given platform (OS
+ compiler). The standard does not define exactly what natural is, so
not much can be read into it.

Is the above correct?

2. If T is type, then it is guaranteed that

sizeof(T*) == sizeof(char*)

What I mean by type here is, roughly, a first-class object that can be
stored in variables, passed into functions, etc. In particular, all
bets are off for functions, since they are not first-class (although
you can have pointers to them). The same for members.

Is the above correct?

3. Digging around in the dinkum C++ docs I see that there is in stddef
a size_t type that is supposed to hold "the result of the sizeof
operator."

So, if for the moment we view memory as a char array and we have a

char* ptr

pointing at the mythical 0 index of this array, then, minus OS
restrictions and what nots,

for (std::size_t i = 0; i < LIM; ++i) {
ptr;
}

would read off all memory. LIM here is the maximum number that
std::size_t can hold.

Correct?

4. LIM can be read off by

#include <limits>

std::size_t LIM = std::numeric_limits<std::size_t>.max()

Correct?

5. stddef also defines ptrdiff_t which is supposed to "store the
result of subtracting two pointers."

Can we guarantee that ptrdiff_t is the signed counterpart of size_t?
Can we guarantee that

sizeof(std::size_t) == sizeof(std::ptrdiff_t)

6. Is there a "big-enough" integral type capable of holding the adress
of every object (Type object as 'defined' above in 2.), e.g. calling
this integral type integer, via a cast as in

T obj;

integer address = (integer)&ptr;

When I made the other post, my impression was that int would do the
job. Then my guess was that std::size_t would suffice, but then I
realized that an address is a type in itself (type of
pointer-to-something) and does not need to come in sizeof(char) = 1
byte units. Hell, it does not even have to be unsigned or have any
relation to integral types whatsoever.

TIA, with my best regards,
G. Rodrigues
 
A

Alf P. Steinbach

* Gonçalo Rodrigues:
Hi all, once again

Thanks to those who replied to my earlier post "2 questions on
primitive types". I have been reading the FAQ and the the dinkum C++
library, so let me make a few more questions so that I can settle
these things on my head.

1. 'int' is the natural signed integral type for a given platform (OS
+ compiler). The standard does not define exactly what natural is, so
not much can be read into it.

Is the above correct?

Yes.

2. If T is type, then it is guaranteed that

sizeof(T*) == sizeof(char*)

What I mean by type here is, roughly, a first-class object that can be
stored in variables, passed into functions, etc. In particular, all
bets are off for functions, since they are not first-class (although
you can have pointers to them). The same for members.

Is the above correct?

No, but you're guaranteed that a T* can be casted to void* and back
preserving the pointer value.

3. Digging around in the dinkum C++ docs I see that there is in stddef
a size_t type that is supposed to hold "the result of the sizeof
operator."

So, if for the moment we view memory as a char array and we have a

char* ptr

pointing at the mythical 0 index of this array, then, minus OS
restrictions and what nots,

for (std::size_t i = 0; i < LIM; ++i) {
ptr;
}

would read off all memory. LIM here is the maximum number that
std::size_t can hold.

Correct?


No, there is a requirement that pointers point to actual objects or to an
imaginary element past the last element in an array, and p+i is only defined
when p and p+i point to the same object or within the same array (including
an imaginary element past the end of the array), and ditto for less-than and
greater-than comparisions.

4. LIM can be read off by

#include <limits>

std::size_t LIM = std::numeric_limits<std::size_t>.max()

Correct?

As the maximum value of std::size_t, yes.

As a maximum memory address, no.

5. stddef also defines ptrdiff_t which is supposed to "store the
result of subtracting two pointers."

Can we guarantee that ptrdiff_t is the signed counterpart of size_t?
Can we guarantee that

sizeof(std::size_t) == sizeof(std::ptrdiff_t)
No.


6. Is there a "big-enough" integral type capable of holding the adress
of every object (Type object as 'defined' above in 2.), e.g. calling
this integral type integer, via a cast as in

T obj;

integer address = (integer)&ptr;

That depends on the implementation, it is not guaranteed to exist.

When I made the other post, my impression was that int would do the
job. Then my guess was that std::size_t would suffice, but then I
realized that an address is a type in itself (type of
pointer-to-something) and does not need to come in sizeof(char) = 1
byte units.

It does. In C and C++ everything is measured in bytes.

Hell, it does not even have to be unsigned

A pointer value isn't signed or unsigned, it's a pointer value.

or have any relation to integral types whatsoever.

reinterpret_cast establishes one such relation, but exactly what the
relation is depends on the implementation. Similarly, output via standard
streams establishes one such relation. And again it's unspecified by the
standard, and depends on the implementation.
 
V

Victor Bazarov

Gonçalo Rodrigues said:
Thanks to those who replied to my earlier post "2 questions on
primitive types". I have been reading the FAQ and the the dinkum C++
library, so let me make a few more questions so that I can settle
these things on my head.

1. 'int' is the natural signed integral type for a given platform (OS
+ compiler). The standard does not define exactly what natural is, so
not much can be read into it.

Is the above correct?

"Read into it"? What's that mean?

There are plenty of things the Standard doesn't define. Like what
a platform is.
2. If T is type, then it is guaranteed that

sizeof(T*) == sizeof(char*)

What I mean by type here is, roughly, a first-class object that can be
stored in variables, passed into functions, etc. In particular, all
bets are off for functions, since they are not first-class (although
you can have pointers to them). The same for members.

Is the above correct?

Well, no. Replace 'char' with 'void' and you get closer. However,
the Standard doesn't say what's involved in the conversion from a T*
to a void*. Especially nothing is said about their sizes being equal.
So, nothing is _guaranteed_. The point was that no existing system
is implemented so that it's not true.
3. Digging around in the dinkum C++ docs I see that there is in stddef
a size_t type that is supposed to hold "the result of the sizeof
operator."

So, if for the moment we view memory as a char array and we have a

char* ptr

pointing at the mythical 0 index of this array, then, minus OS
restrictions and what nots,

for (std::size_t i = 0; i < LIM; ++i) {
ptr;
}

would read off all memory. LIM here is the maximum number that
std::size_t can hold.

Correct?


Since 'ptr' may attempt to dereference memory that doesn't necessarily
exist, the code above has undefined behaviour, so the answer is "no".
4. LIM can be read off by

#include <limits>

std::size_t LIM = std::numeric_limits<std::size_t>.max()

Correct?
Yes.

5. stddef also defines ptrdiff_t which is supposed to "store the
result of subtracting two pointers."

Can we guarantee that ptrdiff_t is the signed counterpart of size_t?

No, _we_ can't guarantee.
Can we guarantee that

sizeof(std::size_t) == sizeof(std::ptrdiff_t)

That would seem a common practice for integral types. An unsigned type
has the same size as its signed counterpart.
6. Is there a "big-enough" integral type capable of holding the adress
of every object (Type object as 'defined' above in 2.), e.g. calling
this integral type integer, via a cast as in

T obj;

integer address = (integer)&ptr;

I think you need to work on your typing skills. Did you mean

integer address = reinterpret_cast<integer>(&obj);

??? I assume that what you typed was a bunch of typos.
When I made the other post, my impression was that int would do the
job.

It would only "do the job" _iff_ such type exists.
> Then my guess was that std::size_t would suffice, but then I
realized that an address is a type in itself (type of
pointer-to-something) and does not need to come in sizeof(char) = 1
byte units.

Yes, it does. A byte is defined as "the minimal individually addressable
portion of memory" (or some such). If the addresses are not expressed in
bytes, there is no way to distinguish between individual bytes, for, say
'read' or 'write' operation on POD objects.
> Hell, it does not even have to be unsigned or have any
relation to integral types whatsoever.

Huh?

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,474
Latest member
AntoniaDea

Latest Threads

Top