473,387 Members | 1,579 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

When/why to use size_t

Why was the size_t type defined in compilers in addition to unsigned
int/long?
When/why should one use size_t?
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn

May 23 '06 #1
12 10654
Alex Vinokur wrote:
Why was the size_t type defined in compilers in addition to unsigned
int/long?
When/why should one use size_t?


size_t was defined as a type to hold the size of an object in C. It is
capable of representing the size of the largest possible object
supported by a C implementation. The sizeof operator yields a value of
this type. You can use size_t to hold the size of objects you declare
and manipulate in your programs. It's slightly more portable and
clearer than using unsigned or unsigned long. But different programmers
have their own preferences in this regard.

May 23 '06 #2
Alex Vinokur wrote:

Why was the size_t type defined in compilers in addition to unsigned
int/long?
In the case where unsigned is big enough to do the job
and also a faster type than long unsigned,
size_t should be unsigned.
In a case where unsigned isn't big enough,
then size_t should be long unsigned, (C89).
When/why should one use size_t?


When counting bytes or elements of an array,
or when interfacing with the return values
of the sizeof operator or functions that return size_t.
I like to match data types in a c program
whenever it's not too difficult.

--
pete
May 23 '06 #3
Alex Vinokur said:
Why was the size_t type defined in compilers in addition to unsigned
int/long?
Because size_t has a different purpose to unsigned int and unsigned long.
Its primary purpose is to be able to contain a value equal to the size of
any object, although it can certainly be used for other things.
When/why should one use size_t?


When one is storing either the size of an object, or a count of objects. To
illustrate this, just look at some of the standard library functions that
use size_t:

int setvbuf(FILE *stream, char *buf, int mode, size_t size);
size_t fread(void *ptr, size_t size, size_t nmemb,
FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
void *calloc(size_t nmemb, size_t size);
void *malloc(size_t size);
void *realloc(void *ptr, size_t size);
void *bsearch(const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
int mblen(const char *s, size_t n);
int mbtowc(wchar_t *pwc, const char *s, size_t n);
size_t mbstowcs(wchar_t *pwcs, const char *s, size_t n);
size_t wcstombs(char *s, const wchar_t *pwcs, size_t n);
void *memcpy(void *s1, const void *s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
char *strncpy(char *s1, const char *s2, size_t n);
char *strncat(char *s1, const char *s2, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
int strncmp(const char *s1, const char *s2, size_t n);
size_t strxfrm(char *s1, const char *s2, size_t n);
void *memchr(const void *s, int c, size_t n);
size_t strcspn(const char *s1, const char *s2);
size_t strspn(const char *s1, const char *s2);
void *memset(void *s, int c, size_t n);
size_t strlen(const char *s);
size_t strftime(char *s, size_t maxsize,
const char *format, const struct tm *timeptr);
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 23 '06 #4
Richard Heathfield wrote:

Alex Vinokur said:

When/why should one use size_t?


When one is storing either the size of an object,
or a count of objects.


I use long unsigned to count the nodes in a list.

I don't think that the maximum number of objects
that can be allocated by malloc,
is related to how many bytes can be in an object.

--
pete
May 23 '06 #5
pete said:
Richard Heathfield wrote:

Alex Vinokur said:

> When/why should one use size_t?


When one is storing either the size of an object,
or a count of objects.


I use long unsigned to count the nodes in a list.

I don't think that the maximum number of objects
that can be allocated by malloc,
is related to how many bytes can be in an object.


That is a fair point, but bear in mind that several standard functions do
take or return size_t for an object count - examples include calloc, fread,
fwrite, strspn, and strlen.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 23 '06 #6
Richard Heathfield wrote:

pete said:
Richard Heathfield wrote:

Alex Vinokur said:

> When/why should one use size_t?

When one is storing either the size of an object,
or a count of objects.


I use long unsigned to count the nodes in a list.

I don't think that the maximum number of objects
that can be allocated by malloc,
is related to how many bytes can be in an object.


That is a fair point,
but bear in mind that several standard functions do
take or return size_t for an object count
- examples include calloc, fread, fwrite, strspn, and strlen.


I use it like this:

static long unsigned node_count(list_type *head)
{
long unsigned count;

for (count = 0; head != NULL; head = head -> next) {
++count;
}
return count;
}

--
pete
May 23 '06 #7
Richard Heathfield <in*****@invalid.invalid> writes:
Alex Vinokur said:
When/why should one use size_t?


When one is storing either the size of an object, or a count of
objects.


It may be worth clarifying that in particular it's appropriate
for storing a count of objects *in memory at any given time*.
When objects are stored on disk, then using a different type may
be worthwhile, because there is, quite possibly, orders of
magnitude more disk space than memory. Similarly, when counting
objects that are not necessarily in memory at one time, e.g. when
objects may be created and destroyed dynamically, then there may
be more objects total over time than can fit in size_t and it may
be reasonable to consider using a different type.
--
"In My Egotistical Opinion, most people's C programs should be indented six
feet downward and covered with dirt." -- Blair P. Houghton
May 23 '06 #8
pete wrote:
.... snip ...
I use it like this:

static long unsigned node_count(list_type *head)
{
long unsigned count;

for (count = 0; head != NULL; head = head -> next) {
++count;
}
return count;
}


Which I would precede with a warning comment about execution time
on circular lists. :-)

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
May 23 '06 #9

"Alex Vinokur" <al****@users.sourceforge.net> wrote
Why was the size_t type defined in compilers in addition to unsigned
int/long?
When/why should one use size_t?

size_t is an uglification of the C language.
A bit like const or noalias, it seems sensible at first sight, but the
implicatins weren't thought through.

OK. Someone might want to allocate more memory than will fit in an int. So
make malloc() take a size_t.
Note that if an int is, as is the intention, the natural size for an integer
on that platform, one needs to ask how an amount of memory can fail to fit
in a register. But pass that by.

So now a string can be szie_t bytes long. So all the string functions need
to take size_t instead of integers, and return them.

Then it gets worse. Any array could have been allocated with malloc(). So
now all you array indices are size_t. So all the counts of array sizes are
size_t as well. So anything that is the result of an operation of a count of
things in the computer is a size_t. So integers virtually disappear from
your code. size_t has run through it.

But size_t's are unsigned. This introduces subtle problems into code.

For instance if we count down a loop
while(N-- > 0)
sudenly the code breaks, because N is of course a count of something, and so
a size_t.

Also, what if we want to subtract two size_ts, for instnace in computing x y
coordinates fro graphics?

It also becomes harder to validate parameters. Image dimensions cannot be
negative. Therefore

void myimagefunction(unsigned char *rgb, int width, int height)
{
assert(width >= 0);
assert(height >= 0)
}

if we are passed random garbage to this function there is a 75% percent
chance of the assets triggering. if the function is called more than a few
times with random garbage, the chance of the assert triggering is
effectively certain.
However width and height are indices, so they've got to be size_t's, since
the image buffer is allocated with malloc().

size_t is a terrible idea that has no place in C code.

--
Buy my book 12 Common Atheist Arguments (refuted)
$1.25 download or $7.20 paper, available www.lulu.com/bgy1mm

May 23 '06 #10
Malcolm said:

"Alex Vinokur" <al****@users.sourceforge.net> wrote
Why was the size_t type defined in compilers in addition to unsigned
int/long?
When/why should one use size_t?
size_t is an uglification of the C language.


I disagree. I think it's a useful abstraction that has an important place in
code. The only thing that's a bit annoying is the need to cast when
printing the darn things - a problem that will go away in about 50 or 60
years, when C99 becomes widespread.

<snip>
So anything that is the result of an operation of a count
of things in the computer is a size_t. So integers virtually disappear
from your code. size_t has run through it.
Personally, I don't see this as a huge problem, or indeed necessarily true.
I am a great fan of size_t, and use it all over the place. And yet, if I
pop into my base development directory on this 'ere machine and do this:

find -name \*.c | xargs grep -w int | wc -l

I find 2565 hits, and another 783 in the headers. To give you something to
compare those numbers with, the figures for size_t are 1229 and 578
respectively.
But size_t's are unsigned. This introduces subtle problems into code.

For instance if we count down a loop
while(N-- > 0)
sudenly the code breaks, because N is of course a count of something, and
so a size_t.
Why is the code broken?

#include <stdio.h>

int main(void)
{
int foo[] = { 0, 1, 2, 3, 4 };
size_t N = sizeof foo / sizeof foo[0];
while(N-- > 0)
{
printf(" %d", foo[N]);
}
putchar('\n');

return 0;
}

Output:

4 3 2 1 0

which is exactly what is expected.

It's true that, after the loop ends, N has the value (size_t)-1, but so
what? It was only a loop counter.
Also, what if we want to subtract two size_ts, for instnace in computing x
y coordinates fro graphics?
Well, in graphics we often want to do rotation and scaling and stuff, and
doing these calcs using integer arithmetic will introduce unacceptable
inaccuracies, so I generally use floating-point for all operations in the
"universe", and then just convert to int at the end for working out an
exact dumping ground for a particular colour. I don't see co-ordinates as
being isomorphic to a number of objects.
It also becomes harder to validate parameters. Image dimensions cannot be
negative.
Just out of curiosity, what meaning would you ascribe to negative image
dimensions? Negative width and height don't make much sense to me.
Therefore

void myimagefunction(unsigned char *rgb, int width, int height)
{
assert(width >= 0);
assert(height >= 0)
}

if we are passed random garbage to this function there is a 75% percent
chance of the assets triggering.
Solution: don't pass random garbage to your functions.
size_t is a terrible idea that has no place in C code.


size_t is a great idea that has an important place in C code.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 23 '06 #11
"Malcolm" <re*******@btinternet.com> writes:
"Alex Vinokur" <al****@users.sourceforge.net> wrote
Why was the size_t type defined in compilers in addition to unsigned
int/long?
When/why should one use size_t?
size_t is an uglification of the C language.
A bit like const or noalias, it seems sensible at first sight, but the
implicatins weren't thought through.

OK. Someone might want to allocate more memory than will fit in an int. So
make malloc() take a size_t.
Note that if an int is, as is the intention, the natural size for an integer
on that platform, one needs to ask how an amount of memory can fail to fit
in a register. But pass that by.


No, let's not pass that by.

There's no requirement for an int to be the size of a register. On a
modern 64-bit system, there's a very good reason for it not to be.
Making int 32 bits allows:
char = 8 bits
short = 16 bits
int = 32 bits
long = 64 bits

If you want to support 8-bit, 16-bit, and 32-bit integers (without
resorting to C99-style extended integer types), you have no choice but
to make int 32 bits.

Using int to represent sizes would make it impossible to have an
object bigger than 2 gigabytes (4 gigabytes if you use unsigned int).
So now a string can be szie_t bytes long. So all the string functions need
to take size_t instead of integers, and return them.

Then it gets worse. Any array could have been allocated with malloc(). So
now all you array indices are size_t. So all the counts of array sizes are
size_t as well. So anything that is the result of an operation of a count of
things in the computer is a size_t. So integers virtually disappear from
your code. size_t has run through it.
Good.
But size_t's are unsigned. This introduces subtle problems into code.

For instance if we count down a loop
while(N-- > 0)
sudenly the code breaks, because N is of course a count of something, and so
a size_t.
Yes, using unsigned types requires some care. Perhaps standardizing
ssize_t, the signed type corresponding to size_t, would have been
helpful.

[snip]
size_t is a terrible idea that has no place in C code.


I disagree.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
May 23 '06 #12

"Malcolm" <re*******@btinternet.com>...
"Alex Vinokur" <al****@users.sourceforge.net> wrote
Why was the size_t type defined in compilers in addition to unsigned
int/long?
When/why should one use size_t?

size_t is an uglification of the C language.

This is an interesting perspective. Is size_t ugly in and of itself, or in
the hands of the hackmeisters?
A bit like const or noalias, it seems sensible at first sight, but the
implicatins weren't thought through. This would surprise me.

[makes his case] size_t is a terrible idea that has no place in C code.

No place whatsoever? Mr. Heathfield lists about twenty places where it
would seem necessary. Is he wrong? Does he mention things that a
reasonable person would never use? I've never used size_t, as I have not
used many of the features of the C language. When I step up to the
compiler, I know darn well the size of the things I'm trying to work with.
But what if, instead of a cowboy on a keyboard, you had to develop with
differing teams and modules. Furthermore, the boss can't even tell you much
about the object until the last phase. I think right about then I'd be
reaching for size_t and a Long Island Iced Tea, but maybe in reverse order.
joe

May 24 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Birt | last post by:
My understanding about defining your own copy and assignment constructors is whenever there is a member of pointer type. Is this true or is there any exception to this"rule"? How about when you...
4
by: Asfand Yar Qazi | last post by:
Sorry about this, but its driving me up the wall. First some code: typedef unsigned int size_t; struct AddOp { template<class I1, class I2> static inline float call(size_t i, const I1&...
6
by: PengYu.UT | last post by:
I'm wondering when I should use ptrdiff_t and size_t instead of int and unsigned int or long and unsigned long? Is there any guideline I should follow? Peng
11
by: javadesigner | last post by:
Hi: I am a bit new to C programming and am trying to write a wrapper around malloc. Since malloc takes size_t as it's parameter, I want to be able to see if my function recieved an argument...
49
by: Neil Zanella | last post by:
Hello, Often I happen to be dealing with nonnegative integers and since I know I won't need negative numbers here I declare them as unsigned simply to make the program somewhat clearer....
22
by: Mike Polinske | last post by:
I am new to the C programming language but have been programming in Cobol for over 10 years. When I compile the following code, it compiles clean but I get an application error both under Windows...
39
by: Mark Odell | last post by:
I've always declared variables used as indexes into arrays to be of type 'size_t'. I have had it brought to my attention, recently, that size_t is used to indicate "a count of bytes" and that using...
89
by: Tubular Technician | last post by:
Hello, World! Reading this group for some time I came to the conclusion that people here are split into several fractions regarding size_t, including, but not limited to, * size_t is the...
6
by: Francois Grieu | last post by:
Hello, I'm asking myself all kind of questions on allocating an array of struct with proper alignment. Is the following code oorrect ? I'm most interested by the statement t =...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.