Can size_t be used as a substitute to unsigned long int ?

P

pereges

For eg :

struct mesh
{
size_t nvert; /* number of vertices */
size_t ntri; /* number of triangles */
.....
};

The reason I want to use size_t is because I've read that it is
capable of supporting size of the largest possible integer in the C
implementation. In my case, the value of nvert can vary from any thing
like 30-40 to even 10 million.
 
H

Harald van Dijk

For eg :

struct mesh
{
size_t nvert; /* number of vertices */
size_t ntri; /* number of triangles */
.....
};

The reason I want to use size_t is because I've read that it is capable
of supporting size of the largest possible integer in the C
implementation.

I doubt that is what you read. It's more likely that you read something
similar, and misunderstood. size_t is capable of holding the size of the
largest possible object in the C implementation, but it's not always, and
maybe not even usually, capable of holding the largest possible integer.
On my system, for example, the largest integer has a value of
18446744073709551615, but I cannot store that in a size_t, and I cannot
even come close to creating any object that large.
 
P

pereges

I doubt that is what you read. It's more likely that you read something
similar, and misunderstood. size_t is capable of holding the size of the
largest possible object in the C implementation, but it's not always, and
maybe not even usually, capable of holding the largest possible integer.
On my system, for example, the largest integer has a value of
18446744073709551615, but I cannot store that in a size_t, and I cannot
even come close to creating any object that large.

But the value that a size_t type variable can hold must be integer ?
Then what do you mean by largest possible object ?
 
R

Richard Tobin

pereges said:
For eg :

struct mesh
{
size_t nvert; /* number of vertices */
size_t ntri; /* number of triangles */
.....
};

The reason I want to use size_t is because I've read that it is
capable of supporting size of the largest possible integer in the C
implementation. In my case, the value of nvert can vary from any thing
like 30-40 to even 10 million.

size_t is appropriate for counting things that are represented as C
objects. It's not necessarily the largest (unsigned) integral type,
but it's effectively a limit on the size of arrays.

It would not be appropriate for counting things that are not
represented by C objects, such as the age of the universe or the
length of a line.

-- Richard
 
V

vippstar

For eg :

struct mesh
{
size_t nvert; /* number of vertices */
size_t ntri; /* number of triangles */
.....

};

The reason I want to use size_t is because I've read that it is
capable of supporting size of the largest possible integer in the C
implementation. In my case, the value of nvert can vary from any thing
like 30-40 to even 10 million.

If you want the largest unsigned integer supported by your
implementation, use uintmax_t (<stdint.h>).
SIZE_MAX (in <limits.h>) is at least 65535.
ULONG_MAX (in <limits.h>) is at least 4294967295.

It's possible that SIZE_MAX > ULONG_MAX.
Find the upper limit, then use a type whose MAX is larger than that
upper limit.
In this case, unsigned long int.
 
S

santosh

pereges said:
But the value that a size_t type variable can hold must be integer ?

The type of size_t is an unsigned integer, so yes, it must hold an
integer value.
Then what do you mean by largest possible object ?

It's the size of the largest object that an implementation could create.
Since the exact size will vary for different implementations (example
it might be 64Kb under small model DOS, or it might be ~4Gb Linux), the
exact type of size_t is implementation defined. The maximum value a
particular instance of size_t can hold is specified by the macro
SIZE_MAX in stdint.h.
 
S

santosh

pereges said:
For eg :

struct mesh
{
size_t nvert; /* number of vertices */
size_t ntri; /* number of triangles */
.....
};

The reason I want to use size_t is because I've read that it is
capable of supporting size of the largest possible integer in the C
implementation. In my case, the value of nvert can vary from any thing
like 30-40 to even 10 million.

Under C90 the largest possible integer value can be represented by
unsigned long[1]. Size_t may not be sufficient, (example it could be
aliased to unsigned int.) For a C99 based system use uintmax_t if you
need the absolute largest supported unsigned integer type.

1. And the signed variants of course.
 
A

Andrey Tarasevich

pereges said:
...
The reason I want to use size_t is because I've read that it is
capable of supporting size of the largest possible integer in the C
implementation.
> ...

That's incorrect. 'size_t's range is big enough to store the size in
bytes of the largest possible object in C implementation. That's it.

It is not guaranteed to be capable of storing such quantities as, for
example, the number of different objects. And, of course, it is not
guaranteed to be the largest possible integer.
 
A

Andrey Tarasevich

Richard said:
...
size_t is appropriate for counting things that are represented as C
objects.
> ...

Maybe I misunderstood you, but there's no guarantee that 'size_t' can
store the total number of C objects I can allocate in dynamic memory.

For example, I can successfully execute 'malloc(1)' more times (i.e.
allocate more 1-byte objects) than 'size_t' can count.
 
V

vippstar

Maybe I misunderstood you, but there's no guarantee that 'size_t' can
store the total number of C objects I can allocate in dynamic memory.

For example, I can successfully execute 'malloc(1)' more times (i.e.
allocate more 1-byte objects) than 'size_t' can count.
And what you'd count is the successful allocations, not 'things that
are represented as C objects'.
So indeed, you have misunderstood.
 
R

Richard

And what you'd count is the successful allocations, not 'things that
are represented as C objects'.
So indeed, you have misunderstood.

But you would not necessarily use a size_t to store that count.

size_t is generally used as a size or length holder, not the number of
times something has been done.

So he is right. Kind of.
 
B

Barry Schwarz

It depends on what you mean by capable.
size_t is capable of being long unsigned in C89
and long long unsigned in C99,
but it doesn't have to be either.


Use long unsigned. It's good for a few trillion.

ULONG_MAX may be as little as 4.3 billion (2**32-1).


Remove del for email
 
P

pereges

I think I will use unsigned long in that case.

struct mesh
{
unsigned long nvert;
unsigned long ntri;
..
};


Is it a good practice to perform a range check on the values entered
by the user ?
 
V

viza

I think I will use unsigned long in that case.

struct mesh
{
unsigned long nvert;
unsigned long ntri;
..
};


Is it a good practice to perform a range check on the values entered by
the user ?

Users generally can't enter integers at all. Almost all user interaction
is through strings. What you need to check is that the function that
converts from a string has not overflowed its output integer type.
Compare strtod() to atoi().
 
R

Richard Tobin

size_t is appropriate for counting things that are represented as C
objects.
[/QUOTE]
Maybe I misunderstood you, but there's no guarantee that 'size_t' can
store the total number of C objects I can allocate in dynamic memory.

That's true. But you're unlikely to need to record a number like that.
Most often you use such a number to size an array, or to calculate
how many bytes to allocate, in which case size_t is appropriate.

I don't think there's guaranteed to be any type that can count
all the allocated objects, though uintptr_t must work if it exists.

-- Richard
 
S

santosh

pereges said:
I think I will use unsigned long in that case.

struct mesh
{
unsigned long nvert;
unsigned long ntri;
..
};


Is it a good practice to perform a range check on the values entered
by the user ?

The standard function strtoul will tell you if what the user enters
cannot be successfully converted or will be too big to fit in an
unsigned int. You will have to manually do any additional program
specific checks (say nvert must be greater than 0 but not greater than
1000.)
 
V

vippstar

The standard function strtoul will tell you if what the user enters
cannot be successfully converted or will be too big to fit in an
unsigned int. You will have to manually do any additional program
^^^^^^^^^^^^
Small correction:
strtoul is about unsigned long int, not unsigned int.
 
V

vippstar

Maybe I misunderstood you, but there's no guarantee that 'size_t' can
store the total number of C objects I can allocate in dynamic memory.

That's true. But you're unlikely to need to record a number like that.
Most often you use such a number to size an array, or to calculate
how many bytes to allocate, in which case size_t is appropriate.

I don't think there's guaranteed to be any type that can count
all the allocated objects, though uintptr_t must work if it exists.[/QUOTE]
uintptr_t is not relevant to counting successful allocations.
It could be that malloc() always succeeds.
Usually there's something else that puts an upper bound.
For example, when you count allocations, you count allocations for /
something/, for example, lines in your text editor.
You can simply put the 'unsigned long' upper bound which is at least
2^32-1, sufficient practically for any text file.
 

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
473,755
Messages
2,569,537
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top