Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #163420 > unrolled thread

on why declare a struct with a single array in it

Started byMeredith Montgomery <mmontgomery@levado.to>
First post2021-11-12 15:48 -0300
Last post2021-11-19 16:07 -0300
Articles 20 on this page of 75 — 20 participants

Back to article view | Back to comp.lang.c


Contents

  on why declare a struct with a single array in it Meredith Montgomery <mmontgomery@levado.to> - 2021-11-12 15:48 -0300
    Re: on why declare a struct with a single array in it Guillaume <message@bottle.org> - 2021-11-12 19:56 +0100
      Re: on why declare a struct with a single array in it Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-12 19:31 +0000
        Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-12 21:07 +0100
          Re: on why declare a struct with a single array in it pozz <pozzugno@gmail.com> - 2021-11-18 15:53 +0100
            Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-18 16:13 +0100
              Re: on why declare a struct with a single array in it Manfred <noname@add.invalid> - 2021-11-18 16:26 +0100
                Re: on why declare a struct with a single array in it pozz <pozzugno@gmail.com> - 2021-11-18 17:22 +0100
                  Re: on why declare a struct with a single array in it Manfred <noname@add.invalid> - 2021-11-18 18:04 +0100
                    Re: on why declare a struct with a single array in it Meredith Montgomery <mmontgomery@levado.to> - 2021-11-19 16:00 -0300
                  Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-18 22:58 +0100
                    Re: on why declare a struct with a single array in it Guillaume <message@bottle.org> - 2021-11-19 17:53 +0100
                      Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-19 11:27 -0800
                        Re: on why declare a struct with a single array in it scott@slp53.sl.home (Scott Lurndal) - 2021-11-19 20:46 +0000
                          Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-19 12:52 -0800
                            Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-20 13:36 +0100
                              Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-20 14:49 +0000
                              Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-20 15:52 -0800
                                Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 00:19 +0000
                                  Re: on why declare a struct with a single array in it Richard Damon <Richard@Damon-Family.org> - 2021-11-20 20:44 -0500
                                    Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-21 14:51 +0100
                                      Re: on why declare a struct with a single array in it Manfred <noname@add.invalid> - 2021-11-21 19:32 +0100
                                        Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-21 21:51 +0100
                                          Re: on why declare a struct with a single array in it Manfred <noname@add.invalid> - 2021-11-22 03:17 +0100
                                            Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-22 11:31 +0100
                                              Re: on why declare a struct with a single array in it Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-12-10 04:21 -0800
                                                Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-12-10 14:43 +0100
                                            Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-22 11:56 +0000
                                            Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-10 01:47 -0800
                                              Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-12-10 10:55 +0000
                                                Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-12-10 14:51 +0100
                                                Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-11 06:56 -0800
                                                  Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-12-11 16:04 +0000
                                                    Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-12-11 17:23 +0000
                                                    Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-01-21 05:30 -0800
                                                      Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2022-01-21 13:49 +0000
                                                  Re: on why declare a struct with a single array in it "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-12-11 12:17 -0800
                                                  Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-12-12 13:00 +0000
                                                    Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-12 08:25 -0800
                                                      Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-12-12 17:38 +0000
                                                        Re: on why declare a struct with a single array in it Dick <thiebauddick2@aol.com> - 2021-12-12 16:19 -0500
                                                          Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-12-13 08:06 +0000
                                                            Re: on why declare a struct with a single array in it Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-12-13 01:30 -0800
                                                          Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-12-13 09:34 +0100
                                                          Re: on why declare a struct with a single array in it Robert Latest <boblatest@yahoo.com> - 2021-12-13 18:53 +0000
                                                            Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-12-13 20:38 +0000
                                                        Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-15 00:38 -0800
                                                          Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-12-15 11:21 +0000
                                                            Re: on why declare a struct with a single array in it Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-12-15 10:26 -0800
                                                          Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-15 10:45 -0800
                                              Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-12-10 10:52 -0800
                                          Re: on why declare a struct with a single array in it Guillaume <message@bottle.org> - 2021-11-22 04:06 +0100
                                            Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-22 11:32 +0000
                                              Re: on why declare a struct with a single array in it Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-22 13:00 -0800
                                      Re: on why declare a struct with a single array in it "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-21 13:08 -0800
                                  Re: on why declare a struct with a single array in it Richard Damon <Richard@Damon-Family.org> - 2021-11-20 20:44 -0500
                                    Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 12:22 +0000
                                  Re: on why declare a struct with a single array in it Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2021-11-20 20:13 -0700
                                    Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 12:35 +0000
                                      Re: on why declare a struct with a single array in it Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2021-11-21 10:53 -0700
                                        Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 18:49 +0000
                                      Re: on why declare a struct with a single array in it "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-21 13:04 -0800
                                  Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 14:42 +0000
                                Re: on why declare a struct with a single array in it Guillaume <message@bottle.org> - 2021-11-21 01:34 +0100
                                  Re: on why declare a struct with a single array in it Bart <bc@freeuk.com> - 2021-11-21 00:48 +0000
                                  Re: on why declare a struct with a single array in it "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-20 16:58 -0800
                                Re: on why declare a struct with a single array in it David Brown <david.brown@hesbynett.no> - 2021-11-21 14:40 +0100
                                  Re: on why declare a struct with a single array in it "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-21 12:59 -0800
                            Re: on why declare a struct with a single array in it scott@slp53.sl.home (Scott Lurndal) - 2021-11-21 15:58 +0000
                          Re: on why declare a struct with a single array in it gazelle@shell.xmission.com (Kenny McCormack) - 2021-11-20 10:55 +0000
    Re: on why declare a struct with a single array in it Jorgen Grahn <grahn+nntp@snipabacken.se> - 2021-11-13 08:47 +0000
      Re: on why declare a struct with a single array in it Guillaume <message@bottle.org> - 2021-11-13 18:23 +0100
    Re: on why declare a struct with a single array in it Kaz Kylheku <480-992-1380@kylheku.com> - 2021-11-13 17:55 +0000
    Re: on why declare a struct with a single array in it Anton Shepelev <anton.txt@g{oogle}mail.com> - 2021-11-19 13:14 +0300
      Re: on why declare a struct with a single array in it Meredith Montgomery <mmontgomery@levado.to> - 2021-11-19 16:07 -0300

Page 1 of 4  [1] 2 3 4  Next page →


#163420 — on why declare a struct with a single array in it

FromMeredith Montgomery <mmontgomery@levado.to>
Date2021-11-12 15:48 -0300
Subjecton why declare a struct with a single array in it
Message-ID<86tughjjm7.fsf@levado.to>
Why would someone put a lonely array inside a structure?

  struct ip_address { unsigned char d[4]; };

Would it be because they want to (in the future) add more members to
this structure?  Because it's not like they can hide this array in the
structure; it's still referenced as

  struct ip_address ip;
  ip.d[0] = ...
  ip.d[1] = ...

But it does look neat, so I guess neatness is the reason?  It's also
easier to read because we're constantly reminded it is an ip address?

[toc] | [next] | [standalone]


#163421

FromGuillaume <message@bottle.org>
Date2021-11-12 19:56 +0100
Message-ID<smmdcc$1n62$1@gioia.aioe.org>
In reply to#163420
Le 12/11/2021 à 19:48, Meredith Montgomery a écrit :
> Why would someone put a lonely array inside a structure?
> 
>    struct ip_address { unsigned char d[4]; };
> 
> Would it be because they want to (in the future) add more members to
> this structure?

That can be a good reason. Anticipating makes for much more maintainable 
code.

But another reason here is that it's a way to make it possible to copy 
arrays. In C, you can't copy arrays.

unsigned char d1[4], d2[4];

d2 = d1; // invalid C

You have to either copy item by item in a loop, or use memcpy() or 
something similar.

If you encapsulate an array in a struct, now you can do it more elegantly:

struct ip_address ip1, ip2;

ip2 = ip1; // perfectly valid C, and will copy the whole array

Of course, if you add members to the struct, it still works and will 
copy all members.

[toc] | [prev] | [next] | [standalone]


#163422

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2021-11-12 19:31 +0000
Message-ID<87pmr5qih6.fsf@bsb.me.uk>
In reply to#163421
Guillaume <message@bottle.org> writes:

> Le 12/11/2021 à 19:48, Meredith Montgomery a écrit :
>> Why would someone put a lonely array inside a structure?
>>    struct ip_address { unsigned char d[4]; };
>> Would it be because they want to (in the future) add more members to
>> this structure?
>
> That can be a good reason. Anticipating makes for much more maintainable code.
>
> But another reason here is that it's a way to make it possible to copy
> arrays. In C, you can't copy arrays.
>
> unsigned char d1[4], d2[4];
>
> d2 = d1; // invalid C
>
> You have to either copy item by item in a loop, or use memcpy() or
> something similar.
>
> If you encapsulate an array in a struct, now you can do it more elegantly:
>
> struct ip_address ip1, ip2;
>
> ip2 = ip1; // perfectly valid C, and will copy the whole array

And a special case of copying is passing values to a function.  That
might even be the /main/ reason for putting an array into a struct,
though only the code's author really knows.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#163423

FromDavid Brown <david.brown@hesbynett.no>
Date2021-11-12 21:07 +0100
Message-ID<smmhhg$bfh$1@dont-email.me>
In reply to#163422
On 12/11/2021 20:31, Ben Bacarisse wrote:
> Guillaume <message@bottle.org> writes:
> 
>> Le 12/11/2021 à 19:48, Meredith Montgomery a écrit :
>>> Why would someone put a lonely array inside a structure?
>>>    struct ip_address { unsigned char d[4]; };
>>> Would it be because they want to (in the future) add more members to
>>> this structure?
>>
>> That can be a good reason. Anticipating makes for much more maintainable code.
>>
>> But another reason here is that it's a way to make it possible to copy
>> arrays. In C, you can't copy arrays.
>>
>> unsigned char d1[4], d2[4];
>>
>> d2 = d1; // invalid C
>>
>> You have to either copy item by item in a loop, or use memcpy() or
>> something similar.
>>
>> If you encapsulate an array in a struct, now you can do it more elegantly:
>>
>> struct ip_address ip1, ip2;
>>
>> ip2 = ip1; // perfectly valid C, and will copy the whole array
> 
> And a special case of copying is passing values to a function.  That
> might even be the /main/ reason for putting an array into a struct,
> though only the code's author really knows.
> 

That is certainly one reason why I do it.  Basically, it means you have
a "value" type that does not decay to a pointer.  It also means the size
is fixed and available via "sizeof" as it is passed around, and perhaps
most importantly it is a specific type.  The "struct ip_address" here is
a named type that cannot be confused with any other array of unsigned
char, nor a pointer to an unsigned char.

[toc] | [prev] | [next] | [standalone]


#163469

Frompozz <pozzugno@gmail.com>
Date2021-11-18 15:53 +0100
Message-ID<sn5pcl$pru$1@dont-email.me>
In reply to#163423
Il 12/11/2021 21:07, David Brown ha scritto:
> On 12/11/2021 20:31, Ben Bacarisse wrote:
>> Guillaume <message@bottle.org> writes:
>>
>>> Le 12/11/2021 à 19:48, Meredith Montgomery a écrit :
>>>> Why would someone put a lonely array inside a structure?
>>>>     struct ip_address { unsigned char d[4]; };
>>>> Would it be because they want to (in the future) add more members to
>>>> this structure?
>>>
>>> That can be a good reason. Anticipating makes for much more maintainable code.
>>>
>>> But another reason here is that it's a way to make it possible to copy
>>> arrays. In C, you can't copy arrays.
>>>
>>> unsigned char d1[4], d2[4];
>>>
>>> d2 = d1; // invalid C
>>>
>>> You have to either copy item by item in a loop, or use memcpy() or
>>> something similar.
>>>
>>> If you encapsulate an array in a struct, now you can do it more elegantly:
>>>
>>> struct ip_address ip1, ip2;
>>>
>>> ip2 = ip1; // perfectly valid C, and will copy the whole array
>>
>> And a special case of copying is passing values to a function.  That
>> might even be the /main/ reason for putting an array into a struct,
>> though only the code's author really knows.
>>
> 
> That is certainly one reason why I do it.  Basically, it means you have
> a "value" type that does not decay to a pointer.  It also means the size
> is fixed and available via "sizeof" as it is passed around, and perhaps
> most importantly it is a specific type.  The "struct ip_address" here is
> a named type that cannot be confused with any other array of unsigned
> char, nor a pointer to an unsigned char.
> 

Regarding your two last sentences, the same can be achieved with:

   typedef unsigned char ip_address[4];

So I don't think those two last arguments are the real reason to embed a 
fixed-sized array into a struct.

[toc] | [prev] | [next] | [standalone]


#163473

FromDavid Brown <david.brown@hesbynett.no>
Date2021-11-18 16:13 +0100
Message-ID<sn5qji$3ri$1@dont-email.me>
In reply to#163469
On 18/11/2021 15:53, pozz wrote:
> Il 12/11/2021 21:07, David Brown ha scritto:
>> On 12/11/2021 20:31, Ben Bacarisse wrote:
>>> Guillaume <message@bottle.org> writes:
>>>
>>>> Le 12/11/2021 à 19:48, Meredith Montgomery a écrit :
>>>>> Why would someone put a lonely array inside a structure?
>>>>>     struct ip_address { unsigned char d[4]; };
>>>>> Would it be because they want to (in the future) add more members to
>>>>> this structure?
>>>>
>>>> That can be a good reason. Anticipating makes for much more
>>>> maintainable code.
>>>>
>>>> But another reason here is that it's a way to make it possible to copy
>>>> arrays. In C, you can't copy arrays.
>>>>
>>>> unsigned char d1[4], d2[4];
>>>>
>>>> d2 = d1; // invalid C
>>>>
>>>> You have to either copy item by item in a loop, or use memcpy() or
>>>> something similar.
>>>>
>>>> If you encapsulate an array in a struct, now you can do it more
>>>> elegantly:
>>>>
>>>> struct ip_address ip1, ip2;
>>>>
>>>> ip2 = ip1; // perfectly valid C, and will copy the whole array
>>>
>>> And a special case of copying is passing values to a function.  That
>>> might even be the /main/ reason for putting an array into a struct,
>>> though only the code's author really knows.
>>>
>>
>> That is certainly one reason why I do it.  Basically, it means you have
>> a "value" type that does not decay to a pointer.  It also means the size
>> is fixed and available via "sizeof" as it is passed around, and perhaps
>> most importantly it is a specific type.  The "struct ip_address" here is
>> a named type that cannot be confused with any other array of unsigned
>> char, nor a pointer to an unsigned char.
>>
> 
> Regarding your two last sentences, the same can be achieved with:
> 
>   typedef unsigned char ip_address[4];
> 
> So I don't think those two last arguments are the real reason to embed a
> fixed-sized array into a struct.
> 

No, it is not the same thing at all.


Try compiling:

	typedef unsigned char ip_address[4];
	ip_address a;
	unsigned char * p = a;

Since "a" is just an array of unsigned char, most uses of it in an
expression decay to a pointer to the first element.  "typedef", despite
the name, does not define a type - it gives an alias to an existing
type.  If you want to make a new type so that pointers to it are
incompatible with other pointer types, you need to put it in a struct
(or a union, but that might seem a little odd).  And wrapping it in a
struct (or union) is the only way to stop this decay, so that the type
retains its value and size even when passed into and out of functions.

[toc] | [prev] | [next] | [standalone]


#163474

FromManfred <noname@add.invalid>
Date2021-11-18 16:26 +0100
Message-ID<sn5rc0$1i81$1@gioia.aioe.org>
In reply to#163473
On 11/18/2021 4:13 PM, David Brown wrote:
> On 18/11/2021 15:53, pozz wrote:
>> Il 12/11/2021 21:07, David Brown ha scritto:
>>> On 12/11/2021 20:31, Ben Bacarisse wrote:
>>>> Guillaume <message@bottle.org> writes:
>>>>
>>>>> Le 12/11/2021 à 19:48, Meredith Montgomery a écrit :
>>>>>> Why would someone put a lonely array inside a structure?
>>>>>>      struct ip_address { unsigned char d[4]; };
>>>>>> Would it be because they want to (in the future) add more members to
>>>>>> this structure?
>>>>>
>>>>> That can be a good reason. Anticipating makes for much more
>>>>> maintainable code.
>>>>>
>>>>> But another reason here is that it's a way to make it possible to copy
>>>>> arrays. In C, you can't copy arrays.
>>>>>
>>>>> unsigned char d1[4], d2[4];
>>>>>
>>>>> d2 = d1; // invalid C
>>>>>
>>>>> You have to either copy item by item in a loop, or use memcpy() or
>>>>> something similar.
>>>>>
>>>>> If you encapsulate an array in a struct, now you can do it more
>>>>> elegantly:
>>>>>
>>>>> struct ip_address ip1, ip2;
>>>>>
>>>>> ip2 = ip1; // perfectly valid C, and will copy the whole array
>>>>
>>>> And a special case of copying is passing values to a function.  That
>>>> might even be the /main/ reason for putting an array into a struct,
>>>> though only the code's author really knows.
>>>>
>>>
>>> That is certainly one reason why I do it.  Basically, it means you have
>>> a "value" type that does not decay to a pointer.  It also means the size
>>> is fixed and available via "sizeof" as it is passed around, and perhaps
>>> most importantly it is a specific type.  The "struct ip_address" here is
>>> a named type that cannot be confused with any other array of unsigned
>>> char, nor a pointer to an unsigned char.
>>>
>>
>> Regarding your two last sentences, the same can be achieved with:
>>
>>    typedef unsigned char ip_address[4];
>>
>> So I don't think those two last arguments are the real reason to embed a
>> fixed-sized array into a struct.
>>
> 
> No, it is not the same thing at all.
> 
> 
> Try compiling:
> 
> 	typedef unsigned char ip_address[4];
> 	ip_address a;
> 	unsigned char * p = a;
> 
> Since "a" is just an array of unsigned char, most uses of it in an
> expression decay to a pointer to the first element.  "typedef", despite
> the name, does not define a type - it gives an alias to an existing
> type.  If you want to make a new type so that pointers to it are
> incompatible with other pointer types, you need to put it in a struct
> (or a union, but that might seem a little odd).  And wrapping it in a
> struct (or union) is the only way to stop this decay, so that the type
> retains its value and size even when passed into and out of functions.
> 

Even more:


$ cat ip_address_array_size.c
#include <stdio.h>

typedef unsigned char ip_address[4];

void foo(ip_address a)
{
   printf("sizeof(a) = %zu\n", sizeof(a)); // sizeof(a) returns 
sizeof(unsigned char*)
}

int main(void)
{
   unsigned char a[] = { 1, 2, 3, 4 };

   foo(a); // unsigned char[4] is valid here
}

$ gcc -std=c11 -O2 -Wall -Wextra ip_address_array_size.c && ./a.out
ip_address_array_size.c: In function ‘foo’:
ip_address_array_size.c:7:37: warning: ‘sizeof’ on array function 
parameter ‘a’ will return size of ‘unsigned char *’ 
[-Wsizeof-array-argument]
     7 |   printf("sizeof(a) = %zu\n", sizeof(a)); // sizeof(a) returns 
sizeof(unsigned char*)
       |                                     ^
ip_address_array_size.c:5:21: note: declared here
     5 | void foo(ip_address a)
       |          ~~~~~~~~~~~^
sizeof(a) = 8

[toc] | [prev] | [next] | [standalone]


#163475

Frompozz <pozzugno@gmail.com>
Date2021-11-18 17:22 +0100
Message-ID<sn5ukn$2ir$1@dont-email.me>
In reply to#163474
Il 18/11/2021 16:26, Manfred ha scritto:
> On 11/18/2021 4:13 PM, David Brown wrote:
>> On 18/11/2021 15:53, pozz wrote:
>>> Il 12/11/2021 21:07, David Brown ha scritto:
>>>> On 12/11/2021 20:31, Ben Bacarisse wrote:
>>>>> Guillaume <message@bottle.org> writes:
>>>>>
>>>>>> Le 12/11/2021 à 19:48, Meredith Montgomery a écrit :
>>>>>>> Why would someone put a lonely array inside a structure?
>>>>>>>      struct ip_address { unsigned char d[4]; };
>>>>>>> Would it be because they want to (in the future) add more members to
>>>>>>> this structure?
>>>>>>
>>>>>> That can be a good reason. Anticipating makes for much more
>>>>>> maintainable code.
>>>>>>
>>>>>> But another reason here is that it's a way to make it possible to 
>>>>>> copy
>>>>>> arrays. In C, you can't copy arrays.
>>>>>>
>>>>>> unsigned char d1[4], d2[4];
>>>>>>
>>>>>> d2 = d1; // invalid C
>>>>>>
>>>>>> You have to either copy item by item in a loop, or use memcpy() or
>>>>>> something similar.
>>>>>>
>>>>>> If you encapsulate an array in a struct, now you can do it more
>>>>>> elegantly:
>>>>>>
>>>>>> struct ip_address ip1, ip2;
>>>>>>
>>>>>> ip2 = ip1; // perfectly valid C, and will copy the whole array
>>>>>
>>>>> And a special case of copying is passing values to a function.  That
>>>>> might even be the /main/ reason for putting an array into a struct,
>>>>> though only the code's author really knows.
>>>>>
>>>>
>>>> That is certainly one reason why I do it.  Basically, it means you have
>>>> a "value" type that does not decay to a pointer.  It also means the 
>>>> size
>>>> is fixed and available via "sizeof" as it is passed around, and perhaps
>>>> most importantly it is a specific type.  The "struct ip_address" 
>>>> here is
>>>> a named type that cannot be confused with any other array of unsigned
>>>> char, nor a pointer to an unsigned char.
>>>>
>>>
>>> Regarding your two last sentences, the same can be achieved with:
>>>
>>>    typedef unsigned char ip_address[4];
>>>
>>> So I don't think those two last arguments are the real reason to embed a
>>> fixed-sized array into a struct.
>>>
>>
>> No, it is not the same thing at all.
>>
>>
>> Try compiling:
>>
>>     typedef unsigned char ip_address[4];
>>     ip_address a;
>>     unsigned char * p = a;
>>
>> Since "a" is just an array of unsigned char, most uses of it in an
>> expression decay to a pointer to the first element.  "typedef", despite
>> the name, does not define a type - it gives an alias to an existing
>> type.  If you want to make a new type so that pointers to it are
>> incompatible with other pointer types, you need to put it in a struct
>> (or a union, but that might seem a little odd).  And wrapping it in a
>> struct (or union) is the only way to stop this decay, so that the type
>> retains its value and size even when passed into and out of functions.
>>
> 
> Even more:
> 
> 
> $ cat ip_address_array_size.c
> #include <stdio.h>
> 
> typedef unsigned char ip_address[4];
> 
> void foo(ip_address a)
> {
>    printf("sizeof(a) = %zu\n", sizeof(a)); // sizeof(a) returns 
> sizeof(unsigned char*)
> }
> 
> int main(void)
> {
>    unsigned char a[] = { 1, 2, 3, 4 };
> 
>    foo(a); // unsigned char[4] is valid here
> }
> 
> $ gcc -std=c11 -O2 -Wall -Wextra ip_address_array_size.c && ./a.out
> ip_address_array_size.c: In function ‘foo’:
> ip_address_array_size.c:7:37: warning: ‘sizeof’ on array function 
> parameter ‘a’ will return size of ‘unsigned char *’ 
> [-Wsizeof-array-argument]
>      7 |   printf("sizeof(a) = %zu\n", sizeof(a)); // sizeof(a) returns 
> sizeof(unsigned char*)
>        |                                     ^
> ip_address_array_size.c:5:21: note: declared here
>      5 | void foo(ip_address a)
>        |          ~~~~~~~~~~~^
> sizeof(a) = 8

Ok, my shame, you're right.

Next time I will think twice before repling.

[toc] | [prev] | [next] | [standalone]


#163477

FromManfred <noname@add.invalid>
Date2021-11-18 18:04 +0100
Message-ID<sn6134$i63$1@gioia.aioe.org>
In reply to#163475
On 11/18/2021 5:22 PM, pozz wrote:
> Il 18/11/2021 16:26, Manfred ha scritto:
>> On 11/18/2021 4:13 PM, David Brown wrote:
>>> On 18/11/2021 15:53, pozz wrote:
>>>> Il 12/11/2021 21:07, David Brown ha scritto:
>>>>> On 12/11/2021 20:31, Ben Bacarisse wrote:
>>>>>> Guillaume <message@bottle.org> writes:
>>>>>>
>>>>>>> Le 12/11/2021 à 19:48, Meredith Montgomery a écrit :
>>>>>>>> Why would someone put a lonely array inside a structure?
>>>>>>>>      struct ip_address { unsigned char d[4]; };
>>>>>>>> Would it be because they want to (in the future) add more 
>>>>>>>> members to
>>>>>>>> this structure?
>>>>>>>
>>>>>>> That can be a good reason. Anticipating makes for much more
>>>>>>> maintainable code.
>>>>>>>
>>>>>>> But another reason here is that it's a way to make it possible to 
>>>>>>> copy
>>>>>>> arrays. In C, you can't copy arrays.
>>>>>>>
>>>>>>> unsigned char d1[4], d2[4];
>>>>>>>
>>>>>>> d2 = d1; // invalid C
>>>>>>>
>>>>>>> You have to either copy item by item in a loop, or use memcpy() or
>>>>>>> something similar.
>>>>>>>
>>>>>>> If you encapsulate an array in a struct, now you can do it more
>>>>>>> elegantly:
>>>>>>>
>>>>>>> struct ip_address ip1, ip2;
>>>>>>>
>>>>>>> ip2 = ip1; // perfectly valid C, and will copy the whole array
>>>>>>
>>>>>> And a special case of copying is passing values to a function.  That
>>>>>> might even be the /main/ reason for putting an array into a struct,
>>>>>> though only the code's author really knows.
>>>>>>
>>>>>
>>>>> That is certainly one reason why I do it.  Basically, it means you 
>>>>> have
>>>>> a "value" type that does not decay to a pointer.  It also means the 
>>>>> size
>>>>> is fixed and available via "sizeof" as it is passed around, and 
>>>>> perhaps
>>>>> most importantly it is a specific type.  The "struct ip_address" 
>>>>> here is
>>>>> a named type that cannot be confused with any other array of unsigned
>>>>> char, nor a pointer to an unsigned char.
>>>>>
>>>>
>>>> Regarding your two last sentences, the same can be achieved with:
>>>>
>>>>    typedef unsigned char ip_address[4];
>>>>
>>>> So I don't think those two last arguments are the real reason to 
>>>> embed a
>>>> fixed-sized array into a struct.
>>>>
>>>
>>> No, it is not the same thing at all.
>>>
>>>
>>> Try compiling:
>>>
>>>     typedef unsigned char ip_address[4];
>>>     ip_address a;
>>>     unsigned char * p = a;
>>>
>>> Since "a" is just an array of unsigned char, most uses of it in an
>>> expression decay to a pointer to the first element.  "typedef", despite
>>> the name, does not define a type - it gives an alias to an existing
>>> type.  If you want to make a new type so that pointers to it are
>>> incompatible with other pointer types, you need to put it in a struct
>>> (or a union, but that might seem a little odd).  And wrapping it in a
>>> struct (or union) is the only way to stop this decay, so that the type
>>> retains its value and size even when passed into and out of functions.
>>>
>>
>> Even more:
>>
>>
>> $ cat ip_address_array_size.c
>> #include <stdio.h>
>>
>> typedef unsigned char ip_address[4];
>>
>> void foo(ip_address a)
>> {
>>    printf("sizeof(a) = %zu\n", sizeof(a)); // sizeof(a) returns 
>> sizeof(unsigned char*)
>> }
>>
>> int main(void)
>> {
>>    unsigned char a[] = { 1, 2, 3, 4 };
>>
>>    foo(a); // unsigned char[4] is valid here
>> }
>>
>> $ gcc -std=c11 -O2 -Wall -Wextra ip_address_array_size.c && ./a.out
>> ip_address_array_size.c: In function ‘foo’:
>> ip_address_array_size.c:7:37: warning: ‘sizeof’ on array function 
>> parameter ‘a’ will return size of ‘unsigned char *’ 
>> [-Wsizeof-array-argument]
>>      7 |   printf("sizeof(a) = %zu\n", sizeof(a)); // sizeof(a) 
>> returns sizeof(unsigned char*)
>>        |                                     ^
>> ip_address_array_size.c:5:21: note: declared here
>>      5 | void foo(ip_address a)
>>        |          ~~~~~~~~~~~^
>> sizeof(a) = 8
> 
> Ok, my shame, you're right.
> 
> Next time I will think twice before repling.

No shame, no problem.
Posts like this give a chance to clarify doubts to other readers as well.

[toc] | [prev] | [next] | [standalone]


#163506

FromMeredith Montgomery <mmontgomery@levado.to>
Date2021-11-19 16:00 -0300
Message-ID<86k0h4km1j.fsf@levado.to>
In reply to#163477
Manfred <noname@add.invalid> writes:

[...]

>> Ok, my shame, you're right.
>> Next time I will think twice before repling.
>
> No shame, no problem.
> Posts like this give a chance to clarify doubts to other readers as well.

So true!

[toc] | [prev] | [next] | [standalone]


#163486

FromDavid Brown <david.brown@hesbynett.no>
Date2021-11-18 22:58 +0100
Message-ID<sn6iam$n5t$1@dont-email.me>
In reply to#163475
On 18/11/2021 17:22, pozz wrote:
> 
> Ok, my shame, you're right.
> 
> Next time I will think twice before repling.

It is a well-known fact that the best way to get an answer on the
internet is not to post a question, but to post the wrong answer!

Arrays and typedefs can be subtle things in C, and are easily
misunderstood - they can seem to work the way you want to start with,
but other things happen when they get passed around via pointers and
function parameters.  It is good to question it like you did - that's
how you learn, and can also aid others in learning.  There is never a
shame in asking a (topical :-) ) question here, nor in making a mistake
and getting corrected.  There's only a shame in not asking when you are
not sure, or not accepting it when a mistake is corrected.

[toc] | [prev] | [next] | [standalone]


#163501

FromGuillaume <message@bottle.org>
Date2021-11-19 17:53 +0100
Message-ID<sn8kq9$tep$1@gioia.aioe.org>
In reply to#163486
Le 18/11/2021 à 22:58, David Brown a écrit :
> It is a well-known fact that the best way to get an answer on the
> internet is not to post a question, but to post the wrong answer!

Very true! :D

> Arrays and typedefs can be subtle things in C, and are easily
> misunderstood - they can seem to work the way you want to start with,
> but other things happen when they get passed around via pointers and
> function parameters.

Well arrays in C are not so subtle, but they can be surprising, 
especially for beginners.

You raise two points here:

1. Arrays are compatible with pointers of the same base type, but since 
C pointers are dumb things that are nothing like "fat" pointers, they 
can't possibly hold any other attribute than a memory location. Thus, 
obviously a pointer can't hold the 'size' of the pointed location. So 
this point should not be particularly confusing, even to beginners. In 
particular, sizeof of a pointer is nothing else than the size of the 
pointer itself. Always. What you assign to the pointer doesn's matter, 
even if it's an array.

Now there are kind of exceptions to that, but that are purely 
"hand-implemented" and have nothing to do with the language itself: for 
instance, the typical malloc() behavior. Behind the scenes, pointers 
returned by malloc() are "fat pointers", and you can also implement your 
own fat pointers if you so wish. But the language doesn't care. It has 
no provision for that, except you can do pointer arithmetics to your 
heart's content.


2. The second point is less well known and admittedly a lot more 
confusing. A function parameter can be an array type, but in this 
particular context, sizeof can't get the size either. That part IS 
definitely confusing, and doesn't make much sense IMHO, but it has 
legacy reasons. Fortunately, decent compilers warn about it, but that 
helps only those who care to read warnings. Which anyone should anyway.

For this second point, I'm not sure it's strictly a problem about arrays 
in C rather than a "problem" with function arguments. Now that 
distinction is subtle indeed.

[toc] | [prev] | [next] | [standalone]


#163508

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2021-11-19 11:27 -0800
Message-ID<87czmwosiq.fsf@nosuchdomain.example.com>
In reply to#163501
Guillaume <message@bottle.org> writes:
> Le 18/11/2021 à 22:58, David Brown a écrit :
>> It is a well-known fact that the best way to get an answer on the
>> internet is not to post a question, but to post the wrong answer!
>
> Very true! :D
>
>> Arrays and typedefs can be subtle things in C, and are easily
>> misunderstood - they can seem to work the way you want to start with,
>> but other things happen when they get passed around via pointers and
>> function parameters.
>
> Well arrays in C are not so subtle, but they can be surprising,
> especially for beginners.

The best explanation I've seen of the often confusing relationship
between arrays and pointers in C is section 6 of the comp.lang.c FAQ:
http://www.c-faq.com/

> You raise two points here:
>
> 1. Arrays are compatible with pointers of the same base type, but
> since C pointers are dumb things that are nothing like "fat" pointers,
> they can't possibly hold any other attribute than a memory
> location. Thus, obviously a pointer can't hold the 'size' of the
> pointed location. So this point should not be particularly confusing,
> even to beginners. In particular, sizeof of a pointer is nothing else
> than the size of the pointer itself. Always. What you assign to the
> pointer doesn's matter, even if it's an array.

Arrays are not "compatible" with pointers.  C has a well defined concept
of type compatibility.  It doesn't refer to types that can be assigned
to each other.

Every pointer value refers to a memory address *and* (other than void*)
specifies the type of the object it points to .  That type information
includes the size of the target type.  The size information isn't
contained in the pointer object, any more than an int object contains
the value of sizeof (int).  A pointer to an *element* of an array object
doesn't tell us the size of the array object.

> Now there are kind of exceptions to that, but that are purely
> "hand-implemented" and have nothing to do with the language itself:
> for instance, the typical malloc() behavior. Behind the scenes,
> pointers returned by malloc() are "fat pointers", and you can also
> implement your own fat pointers if you so wish. But the language
> doesn't care. It has no provision for that, except you can do pointer
> arithmetics to your heart's content.

I'm not sure what you mean about malloc() returning "fat pointers".
malloc() returns a void* with no information about the size or type of
what it points to.  Some implementations might provide a way to query
the size of the allocated space, but that's not standard.

> 2. The second point is less well known and admittedly a lot more
> confusing. A function parameter can be an array type, but in this 
> particular context, sizeof can't get the size either. That part IS
> definitely confusing, and doesn't make much sense IMHO, but it has 
> legacy reasons. Fortunately, decent compilers warn about it, but that
> helps only those who care to read warnings. Which anyone should
> anyway.
>
> For this second point, I'm not sure it's strictly a problem about
> arrays in C rather than a "problem" with function arguments. Now that 
> distinction is subtle indeed.

There are two basic rules to remember.

First, an expression of array type is, in most contexts, "converted" to
a pointer expression whose value points to the initial element of the
array object.  (This is a compile-time adjustment, not a run-time
conversion).  The exceptions are the argument of sizeof, the argument of
unary "&", and a string literal in an initializer used to initialize an
array object; in those contexts, array expressions remain as array
expressions.

Second, a parameter defined with an array type is adjusted to a pointer
type.  This:
    void func(int param[42]);
is *exactly* equivalent to:
    void func(int *param);

All the weird interactions between arrays and pointers, including the
behavior of multidimensional arrays (which are simply arrays of arrays),
follow from those two rules.

One consequence of these rules is that we usually manipulate array
objects via pointers to their elements, because most operations that
would act on array objects as a whole don't exist.

Something else I've found useful is to treat the words "array" and
"pointer" as adjectives, not nouns.  Informally we can say "this is an
array", but it can be ambiguous.  Instead, we can have an array type, an
array object, an array expression, an array value, etc. (where "an array
FOO" is "a FOO of array type" for FOO!=type).

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

[toc] | [prev] | [next] | [standalone]


#163512

Fromscott@slp53.sl.home (Scott Lurndal)
Date2021-11-19 20:46 +0000
Message-ID<Y2UlJ.79170$ya3.75666@fx38.iad>
In reply to#163508
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>Guillaume <message@bottle.org> writes:
>> Le 18/11/2021 à 22:58, David Brown a écrit :

>> Now there are kind of exceptions to that, but that are purely
>> "hand-implemented" and have nothing to do with the language itself:
>> for instance, the typical malloc() behavior. Behind the scenes,
>> pointers returned by malloc() are "fat pointers", and you can also
>> implement your own fat pointers if you so wish. But the language
>> doesn't care. It has no provision for that, except you can do pointer
>> arithmetics to your heart's content.
>
>I'm not sure what you mean about malloc() returning "fat pointers".
>malloc() returns a void* with no information about the size or type of
>what it points to.  Some implementations might provide a way to query
>the size of the allocated space, but that's not standard.

Many malloc implementations reserve additional space, either before
or after the allocated space for bookkeeping and alignment purposes.

Perhaps that is the source of Guillaume's "fat pointer" reference.

[toc] | [prev] | [next] | [standalone]


#163513

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2021-11-19 12:52 -0800
Message-ID<874k87q35r.fsf@nosuchdomain.example.com>
In reply to#163512
scott@slp53.sl.home (Scott Lurndal) writes:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>Guillaume <message@bottle.org> writes:
>>> Le 18/11/2021 à 22:58, David Brown a écrit :
>
>>> Now there are kind of exceptions to that, but that are purely
>>> "hand-implemented" and have nothing to do with the language itself:
>>> for instance, the typical malloc() behavior. Behind the scenes,
>>> pointers returned by malloc() are "fat pointers", and you can also
>>> implement your own fat pointers if you so wish. But the language
>>> doesn't care. It has no provision for that, except you can do pointer
>>> arithmetics to your heart's content.
>>
>>I'm not sure what you mean about malloc() returning "fat pointers".
>>malloc() returns a void* with no information about the size or type of
>>what it points to.  Some implementations might provide a way to query
>>the size of the allocated space, but that's not standard.
>
> Many malloc implementations reserve additional space, either before
> or after the allocated space for bookkeeping and alignment purposes.
>
> Perhaps that is the source of Guillaume's "fat pointer" reference.

Perhaps -- but typically that information is not stored in the pointer
itself.  If it were, all void* values would have to store that extra
information.

(I think it's easier to store bookkeeping data before the allocated
space.  If you store it after the space, it's hard to know where it is.)

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

[toc] | [prev] | [next] | [standalone]


#163522

FromDavid Brown <david.brown@hesbynett.no>
Date2021-11-20 13:36 +0100
Message-ID<snaq53$voh$1@dont-email.me>
In reply to#163513
On 19/11/2021 21:52, Keith Thompson wrote:
> scott@slp53.sl.home (Scott Lurndal) writes:
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>> Guillaume <message@bottle.org> writes:
>>>> Le 18/11/2021 à 22:58, David Brown a écrit :
>>
>>>> Now there are kind of exceptions to that, but that are purely
>>>> "hand-implemented" and have nothing to do with the language itself:
>>>> for instance, the typical malloc() behavior. Behind the scenes,
>>>> pointers returned by malloc() are "fat pointers", and you can also
>>>> implement your own fat pointers if you so wish. But the language
>>>> doesn't care. It has no provision for that, except you can do pointer
>>>> arithmetics to your heart's content.
>>>
>>> I'm not sure what you mean about malloc() returning "fat pointers".
>>> malloc() returns a void* with no information about the size or type of
>>> what it points to.  Some implementations might provide a way to query
>>> the size of the allocated space, but that's not standard.
>>
>> Many malloc implementations reserve additional space, either before
>> or after the allocated space for bookkeeping and alignment purposes.
>>
>> Perhaps that is the source of Guillaume's "fat pointer" reference.
> 
> Perhaps -- but typically that information is not stored in the pointer
> itself.  If it were, all void* values would have to store that extra
> information.
> 
> (I think it's easier to store bookkeeping data before the allocated
> space.  If you store it after the space, it's hard to know where it is.)
> 

That's the most common way for a simple malloc/free system.

It has always struck me as a mistake that C did things that way - in my
opinion, "free" should have taken an additional parameter of the size
for the deallocation.

[toc] | [prev] | [next] | [standalone]


#163523

FromBart <bc@freeuk.com>
Date2021-11-20 14:49 +0000
Message-ID<snb1u4$ppq$1@dont-email.me>
In reply to#163522
On 20/11/2021 12:36, David Brown wrote:
> On 19/11/2021 21:52, Keith Thompson wrote:
>> scott@slp53.sl.home (Scott Lurndal) writes:
>>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>>> Guillaume <message@bottle.org> writes:
>>>>> Le 18/11/2021 à 22:58, David Brown a écrit :
>>>
>>>>> Now there are kind of exceptions to that, but that are purely
>>>>> "hand-implemented" and have nothing to do with the language itself:
>>>>> for instance, the typical malloc() behavior. Behind the scenes,
>>>>> pointers returned by malloc() are "fat pointers", and you can also
>>>>> implement your own fat pointers if you so wish. But the language
>>>>> doesn't care. It has no provision for that, except you can do pointer
>>>>> arithmetics to your heart's content.
>>>>
>>>> I'm not sure what you mean about malloc() returning "fat pointers".
>>>> malloc() returns a void* with no information about the size or type of
>>>> what it points to.  Some implementations might provide a way to query
>>>> the size of the allocated space, but that's not standard.
>>>
>>> Many malloc implementations reserve additional space, either before
>>> or after the allocated space for bookkeeping and alignment purposes.
>>>
>>> Perhaps that is the source of Guillaume's "fat pointer" reference.
>>
>> Perhaps -- but typically that information is not stored in the pointer
>> itself.  If it were, all void* values would have to store that extra
>> information.
>>
>> (I think it's easier to store bookkeeping data before the allocated
>> space.  If you store it after the space, it's hard to know where it is.)
>>
> 
> That's the most common way for a simple malloc/free system.
> 
> It has always struck me as a mistake that C did things that way - in my
> opinion, "free" should have taken an additional parameter of the size
> for the deallocation.

Yeah, that's how I always implemented deallocations in the days when I 
had to code everthing.

I was suprised when I first came across C's free which magically didn't 
need that info!

Rather an indulgence for a lower level systems language.

When I go to some pains to allocate a block of exactly 4096 bytes, I 
expect the next 4096-byte block to follow immediately, not be offset 
from it by 4, 8 or 28 bytes or however it decides to do it.

Worse if my block is only 8 or 16 bytes:

     for (int i=0; i<10; ++i) {
         p=malloc(8);
         printf("%d\n",(int)p);
     }

The first three compilers I tried (I think all using msvcrt), used 32 
bytes per allocation. 300% overhead!

[toc] | [prev] | [next] | [standalone]


#163533

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2021-11-20 15:52 -0800
Message-ID<875ysmjsfz.fsf@nosuchdomain.example.com>
In reply to#163522
David Brown <david.brown@hesbynett.no> writes:
> On 19/11/2021 21:52, Keith Thompson wrote:
[...]
>> Perhaps -- but typically that information is not stored in the pointer
>> itself.  If it were, all void* values would have to store that extra
>> information.
>> 
>> (I think it's easier to store bookkeeping data before the allocated
>> space.  If you store it after the space, it's hard to know where it is.)
>
> That's the most common way for a simple malloc/free system.
>
> It has always struck me as a mistake that C did things that way - in my
> opinion, "free" should have taken an additional parameter of the size
> for the deallocation.

Meh.  That would have introduced another rich source of programming
errors (passing the wrong size).  Probably most implementations would
have kept track of the size anyway, so they could detect errors.  As
long as they're keeping track, why make the user do so as well?

Perhaps a lower-level allocator might be more efficient if user code is
required to keep track, but I don't think it would be all that useful
for most applications.

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

[toc] | [prev] | [next] | [standalone]


#163534

FromBart <bc@freeuk.com>
Date2021-11-21 00:19 +0000
Message-ID<snc3a0$6gs$1@dont-email.me>
In reply to#163533
On 20/11/2021 23:52, Keith Thompson wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 19/11/2021 21:52, Keith Thompson wrote:
> [...]
>>> Perhaps -- but typically that information is not stored in the pointer
>>> itself.  If it were, all void* values would have to store that extra
>>> information.
>>>
>>> (I think it's easier to store bookkeeping data before the allocated
>>> space.  If you store it after the space, it's hard to know where it is.)
>>
>> That's the most common way for a simple malloc/free system.
>>
>> It has always struck me as a mistake that C did things that way - in my
>> opinion, "free" should have taken an additional parameter of the size
>> for the deallocation.
> 
> Meh.  That would have introduced another rich source of programming
> errors (passing the wrong size).

You could also pass the wrong size to malloc, or the wrong pointer to free.

> Probably most implementations would
> have kept track of the size anyway, so they could detect errors.

I doubt that, unless it's for debugging mode.

If an application needs to allocate 100 million 32-byte nodes, which 
would occupy 3.2GB by themselves, how much extra would be needed for the 
size, 'just for checking'?

On my machine that seems to be 16 bytes per node, so 50% more. 1.6GB 
extra just so someone can write:

    free(p);

instead of:

    free(p, sizeof(treenode));

possibly in just one place in the program.

It doesn't make sense.

[toc] | [prev] | [next] | [standalone]


#163538

FromRichard Damon <Richard@Damon-Family.org>
Date2021-11-20 20:44 -0500
Message-ID<KvhmJ.55056$np6.2360@fx46.iad>
In reply to#163534
On 11/20/21 7:19 PM, Bart wrote:
> On 20/11/2021 23:52, Keith Thompson wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>> On 19/11/2021 21:52, Keith Thompson wrote:
>> [...]
>>>> Perhaps -- but typically that information is not stored in the pointer
>>>> itself.  If it were, all void* values would have to store that extra
>>>> information.
>>>>
>>>> (I think it's easier to store bookkeeping data before the allocated
>>>> space.  If you store it after the space, it's hard to know where it 
>>>> is.)
>>>
>>> That's the most common way for a simple malloc/free system.
>>>
>>> It has always struck me as a mistake that C did things that way - in my
>>> opinion, "free" should have taken an additional parameter of the size
>>> for the deallocation.
>>
>> Meh.  That would have introduced another rich source of programming
>> errors (passing the wrong size).
> 
> You could also pass the wrong size to malloc, or the wrong pointer to free.
> 
>> Probably most implementations would
>> have kept track of the size anyway, so they could detect errors.
> 
> I doubt that, unless it's for debugging mode.
> 
> If an application needs to allocate 100 million 32-byte nodes, which 
> would occupy 3.2GB by themselves, how much extra would be needed for the 
> size, 'just for checking'?
> 
> On my machine that seems to be 16 bytes per node, so 50% more. 1.6GB 
> extra just so someone can write:
> 
>     free(p);
> 
> instead of:
> 
>     free(p, sizeof(treenode));
> 
> possibly in just one place in the program.
> 
> It doesn't make sense.
> 

Maybe not to you, but I would sure hate to have to keep track of all 
that data, and would likely just wrap this dumb malloc with something 
smarter.

If you need a lot of a fixed sized blocks, there are lots of algorithms 
that work well for that with much less or zero overhead (if the blocks 
are big enough for a pointer)

[toc] | [prev] | [next] | [standalone]


Page 1 of 4  [1] 2 3 4  Next page →

Back to top | Article view | comp.lang.c


csiph-web