Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

memset and data types

81 views
Skip to first unread message

DFS

unread,
Feb 20, 2024, 8:07:39 AMFeb 20
to
void *memset(void *str, int c, size_t n)

I saw that memset accepts ints where n <= INT_MAX, but above that
requires n to be a size_t (or similar) variable.

Why does the function definition specify size_t?

James Kuyper

unread,
Feb 20, 2024, 10:36:28 AMFeb 20
to
Because size_t is intended to be the type used for the size of objects.
A typical use would be memset(&obj, 0, sizeof obj), or memset(array, 0,
sizeof array). Many implementations allow objects with a size too large
to be represented by an int, while size_t is supposed to be (but is not
required to be) large enough to represent the size of any creatable object.

Kenny McCormack

unread,
Feb 20, 2024, 12:46:57 PMFeb 20
to
In article <ur2gtc$2ih6n$1...@dont-email.me>,
The real answer is that when there is a prototype in scope (as there will
be if you are doing things right), then when you pass an int as the 3rd
arg, it gets promoted to size_t in the call. I.e., the called function
always "sees" a size_t as the last argument (regardless of what you
actually passed in the call).

--
The randomly chosen signature file that would have appeared here is more than 4
lines long. As such, it violates one or more Usenet RFCs. In order to remain
in compliance with said RFCs, the actual sig can be found at the following URL:
http://user.xmission.com/~gazelle/Sigs/CLCtopics

Keith Thompson

unread,
Feb 20, 2024, 12:49:44 PMFeb 20
to
I believe C23 requires all objects to be no more than SIZE_MAX bytes.


--
Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
Working, but not speaking, for Medtronic
void Void(void) { Void(); } /* The recursive call of the void */

Peter 'Shaggy' Haywood

unread,
Feb 21, 2024, 8:07:46 AMFeb 21
to
Groovy hepcat DFS was jivin' in comp.lang.c on Wed, 21 Feb 2024 12:07
am. It's a cool scene! Dig it.

> void *memset(void *str, int c, size_t n)
>
> I saw that memset accepts ints where n <= INT_MAX, but above that

Where did you see that? There is no such wording in the standard. From
N3096:

**********************************************************************
7.26.6.1 The memset function

Synopsis
1 #include <string.h>
void *memset(void *s, int c, size_t n);

Description
2 The memset function copies the value of c (converted to an unsigned
char) into each of the first n characters of the object pointed to by
s.

Returns
3 The memset function returns the value of s.
**********************************************************************

I don't think this has changed at all, save section numbering, since the
first version of the standard came out. (Has it, folks?)
And, as you can see, there's no stipulation that n <= INT_MAX. Is this
perhaps a limitation of the implementation you're using?

> requires n to be a size_t (or similar) variable.
> Why does the function definition specify size_t?

Are you kidding? It's the size parameter. Duh! What else would it be
but a size_t? That's what that type is for.
I sometimes use size_t for other things, because it just sort of fits
those uses. But the main purpose of size_t is to represent sizes.
D'ya have any more silly questions, hmm?

--


----- Dig the NEW and IMPROVED news sig!! -----


-------------- Shaggy was here! ---------------
Ain't I'm a dawg!!

bart

unread,
Feb 21, 2024, 8:37:43 AMFeb 21
to
On 20/02/2024 13:07, DFS wrote:
> void *memset(void *str, int c, size_t n)
>
> I saw that memset accepts ints where n <= INT_MAX,

Where did you see that?

> but above that
> requires n to be a size_t (or similar) variable.
>
> Why does the function definition specify size_t?

On a 64-bit machine, you need to be able to work on memory blocks which
are bigger than 2GB, which is the limit if n had an int type.

On 32-bit and smaller, then size_t will probably be limited to 32 or 16
bits. But `int` would still be insufficient, as it needs to be unsigned
to allow counts above 0x7FFFFFFF or above 0x7FFF.

Keith Thompson

unread,
Feb 21, 2024, 10:45:51 AMFeb 21
to
DFS <nos...@dfs.com> writes:
> void *memset(void *str, int c, size_t n)
>
> I saw that memset accepts ints where n <= INT_MAX, but above that
> requires n to be a size_t (or similar) variable.

That's strictly true, but it's an odd way to say it.

You can certainly pass an int value as the third argument to memset(),
and of course any int value must be <= INT_MAX. It will be implicitly
converted from int to size_t. (It's conceivable, but implausible, that
INT_MAX could be greater than SIZE_MAX.)

The argument can be of any arithmetic type, and it will be converted to
size_t, but it usually makes sense for the argument to be of the
parameter type. There's nothing special about int in this context.

> Why does the function definition specify size_t?

Because it's a size.

James Kuyper

unread,
Feb 21, 2024, 11:19:51 AMFeb 21
to
On 2/20/24 12:49, Keith Thompson wrote:
> James Kuyper <james...@alumni.caltech.edu> writes:
...
>> Because size_t is intended to be the type used for the size of objects.
>> A typical use would be memset(&obj, 0, sizeof obj), or memset(array, 0,
>> sizeof array). Many implementations allow objects with a size too large
>> to be represented by an int, while size_t is supposed to be (but is not
>> required to be) large enough to represent the size of any creatable object.
>
> I believe C23 requires all objects to be no more than SIZE_MAX bytes.

True: "A complete type shall have a size that is less than or equal to
SIZE_MAX." (6.2.5p28)

Sorry - I haven't had time to absorb all of the changes made in c2023 yet.

0 new messages