• memset and data types

    From DFS@21:1/5 to All on Tue Feb 20 08:07:26 2024
    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?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to DFS on Tue Feb 20 10:36:12 2024
    On 2/20/24 08:07, DFS wrote:
    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?

    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to [email protected] on Tue Feb 20 17:46:42 2024
    In article <ur2gtc$2ih6n$[email protected]>,
    James Kuyper <[email protected]> wrote:
    On 2/20/24 08:07, DFS wrote:
    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?

    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.


    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Peter 'Shaggy' Haywood@21:1/5 to All on Wed Feb 21 15:12:58 2024
    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!!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From bart@21:1/5 to DFS on Wed Feb 21 13:37:27 2024
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to Keith Thompson on Wed Feb 21 11:19:34 2024
    On 2/20/24 12:49, Keith Thompson wrote:
    James Kuyper <[email protected]> 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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)