Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #163420 > unrolled thread
| Started by | Meredith Montgomery <mmontgomery@levado.to> |
|---|---|
| First post | 2021-11-12 15:48 -0300 |
| Last post | 2021-11-19 16:07 -0300 |
| Articles | 20 on this page of 75 — 20 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Meredith Montgomery <mmontgomery@levado.to> |
|---|---|
| Date | 2021-11-12 15:48 -0300 |
| Subject | on 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]
| From | Guillaume <message@bottle.org> |
|---|---|
| Date | 2021-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-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]
| From | pozz <pozzugno@gmail.com> |
|---|---|
| Date | 2021-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-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]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2021-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]
| From | pozz <pozzugno@gmail.com> |
|---|---|
| Date | 2021-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]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2021-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]
| From | Meredith Montgomery <mmontgomery@levado.to> |
|---|---|
| Date | 2021-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-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]
| From | Guillaume <message@bottle.org> |
|---|---|
| Date | 2021-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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-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]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-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]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2021-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