#Axioms on size_t and intptr_t

25 messages · Page 1 of 1 (latest)

humble fern
#

I have a few misunderstanding (or points of hesitations) about size_t and intptr_t

as far as I know intptr_t guarantees some pointer difference might fit that type, and size_t is the range type of sizeof . In a setup where I have a memory of 2^128 bytes, could size_t and intptr_t be only defined on 64 bits?
that would be a good scenario because from the inside of C, I guess I won't be able to create a piece of data for a number larger than 2^64, so chill. But if I do allocate 2^64 bytes in a char array for example, it means the difference between the start and the end would exceed intptr_t capacity. This is fine a per the spec: intptr_t is not mandated to represent every pointer difference.

Now in a scenario where the memory is only 2^53 bytes for example, and both intptr_t and size_t are on 64 bits, then I see that I can fairly represent every data size as a size_t and once I allocated a char[] for example, I can subtract the start and the end and get a validintptr_t. However, the converse is now false: not every intptr_t represents a valid pointer difference. Given a start char* p and a diff intptr_t d, I don't have p+d guaranteed to point somewhere legal

is everything here already correct?

Are there existing properties (from the spec, C99) that allows for some interplay between size_t and intptr_t , or uintptr_t ? Because as far as I understand right now, those two types seem to be fairly independent and not a lot can be said to go from one to another

final coyoteBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

unique seal
#

If you were working with an 8 bit machine, those types would be 8 bits in size. For 16 bit machines, they are 16 bits. This is relevent if you are working with embeded systems.

humble fern
#

my main point of concern is that it feels like , it's not because some object can be allocated , that end-start will be well-defined; for example:

char foo[VERY_BIG_NUMBER];
sizeof(foo) == VERY_BIG_NUMBER; // is that true? I suppose
char *end = foo+VERY_BIG_NUMBER;
end - foo == VERY_BIG_NUMBER; // that doesn't seem to hold always
coral bane
#

It's not intptr_t that's meant for pointer arithmetic, it's ptrdiff_t. intptr_t (and uintptr_t) are simply integer types wide enough to store a pointer.

coral bane
#

There's an implicit assumption in the question that the upper bound of pointer arithmetic is 2⁶⁴-1 or 2³²-1, but it's not.

#

I.e. 2⁶³-1 or 2³¹-1

#

;compile ```c
#include <limits.h>
#include <stdint.h>

// using empty struct as the type
// to demonstrate array limits
static const struct {} a[SIZE_MAX];

cerulean furnaceBOT
#
Compiler Output
<source>: In function 'main':
<source>:8:24: error: size of array 'a' is too large
    8 | static const struct {} a[SIZE_MAX];
      |                        ^
Build failed
coral bane
#

;compile ```c
#include <limits.h>
#include <stdint.h>

// using empty struct as the type
// to demonstrate array limits
static const struct {} a[PTRDIFF_MAX];

cerulean furnaceBOT
#
Compilation successful

No output.

coral bane
#

Trying to actually define an array as large as theoretically possible is not allowed.

humble fern
#

I meant ptrdiff_t indeed

humble fern
humble fern
humble fern
#

ah dang, sorry. jeesus, I'm so off tonight

#

int

#

I mean, the minimal for those types coincides with the minimal for int

#

I guess in practice, for regular usages, it means that unless you deal with objects reaaaaaally big, you just don't really care ?

coral bane