Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #110812
| Path | csiph.com!weretis.net!feeder6.news.weretis.net!feeder.usenetexpress.com!feeder1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!buffer1.nntp.dca1.giganews.com!news.giganews.com.POSTED!not-for-mail |
|---|---|
| NNTP-Posting-Date | Sat, 27 May 2017 23:16:24 -0500 |
| Message-Id | <2cnnvd-ub5.ln1@walter.foo> |
| From | "Peter \"Shaggy\" Haywood" <phaywood@alphalink.com.au> |
| Subject | Re: sizeof(x) / sizeof(x[0]) |
| Newsgroups | comp.lang.c |
| Date | Sat, 27 May 2017 17:44:33 +1000 |
| References | <1420cd8f-e5cb-4a8f-93e6-d80a8b050650@googlegroups.com> <59252557$0$15332$426a74cc@news.free.fr> |
| User-Agent | KNode/0.10.9 |
| MIME-Version | 1.0 |
| Content-Type | text/plain; charset=utf-8 |
| Content-Transfer-Encoding | 8Bit |
| Lines | 147 |
| X-Usenet-Provider | http://www.giganews.com |
| X-Trace | sv3-1ZvwIm+lTp01pAnNR6kbgrO5yufp0if+dR5I868zLzL78Y1b/uI+yJhcLKN/0obEv3XnQxwuLRhSfKB!0zEhRjRTZ2v+VT01+vicJaVHb5iZ9tRHumgTwBKCY5yny+z+ |
| X-Complaints-To | abuse@giganews.com |
| X-DMCA-Notifications | http://www.giganews.com/info/dmca.html |
| X-Abuse-and-DMCA-Info | Please be sure to forward a copy of ALL headers |
| X-Abuse-and-DMCA-Info | Otherwise we will be unable to process your complaint properly |
| X-Postfilter | 1.3.40 |
| X-Original-Bytes | 6966 |
| Xref | csiph.com comp.lang.c:110812 |
Show key headers only | View raw
Groovy hepcat Patrick.Schluter was jivin' in comp.lang.c on Wed, 24 May
2017 4:16 pm. It's a cool scene! Dig it.
> Le 14.01.2017 à 13:16, Alla _ a écrit :
>> Hello!
I haven't seen the original post nor any followup except the one to
which I'm following up, so forgive me if this has already been covered.
>> Please, read my explanation before answering, to show
>> my mistake.
>> Honestly, for some time now I was sure I have no problems
>> with the statement sizeof(x) / sizeof(x[0]), usually used as
>> the macro to compute the size of an array of strings. I was
>> positive that I know how it works, and didn't doubt.
>> Somehow today when I used this macro again I've experienced
>> a confusion - how does it work, and what have I completely
>> forgotten? Although shameful, I have decided to come here again
>> for help on this matter.
It's unbelievably simple! The number of array elements can be
calculated as the total size of the array divided by the size of a
single element.
>> For example:
>> char *array[] = {"abc", "defg", "hijklmop", NULL};
>> The pointer points to an array that has 4 strings.
What pointer? There are 4 pointers here, all inside the array. It is
an array of pointer to char with 4 elements, after all. There is no
other pointer here.
>> sizeof(x) here will be sizeof(array) thus indicating
>> the size in bytes of the whole array of strings,
>> because 'array' here is used as the address of the
>> first sub-element, which is 'a' (array is the same as
>> array[0][0]);
What? That makes no sense at all! You're completely confused, Alla_.
>> so sizeof(array) will give the number of bytes occupied
>> by the whole array of strings, i.e. number
There is really no such thing as an array of strings. Why are people
often so confused by this concept? A string is really a data format,
not a type. It's a sequence of characters ending with a null character.
This can be stored in an array or a block of dynamically allocated
memory. A string literal is an (unnamed) array of char containing a
string.
An array could be an array of arrays (commonly called a 2 dimentional
array) of char containing strings. Alternatively, it could be an array
of pointers, each of which may point at (the first element of) an array
of char or dynamically allocated memory containing a string. Or it
could be an array of some other type.
>> of characters x 1 (which is the size of a char);
The size of an array is the size of a single element multiplied by the
number of elements. The size of an array such as the one named array in
the example above is, in bytes, sizeof (char *) multiplied by 4. The
expression sizeof array yields this value, while sizeof array[0] gives
the size of a single array element (char * in this case).
>> the denominator sizeof(x[0]) gives the size of the
>> first element of the array,
Right.
>> i.e. the size of the first
>> string, which is here "abc", so it it is 3 (3 characters,
Wrong! What is the type of your array? It's char *[4] (4 element array
of pointer to char), right? So what type is an element of this array?
It's char * (pointer to char), obviously.
>> each 1 byte); and all other strings have different
>> number of characters in them, and hence different
>> number of bytes;
>>
>> how then sizeof(x) / sizeof(x[0]) gives a correct number
>> of strings in the array (it actually does, I have tested it
It doesn't give the number of strings. It gives the number of array
elements. Forget about strings for the moment. The size of an array
divided by the size of one of its elements yields the number of
elements, regardless of the type of that element and the format of data
(string or otherwise) stored therein.
>> on different strings)? Please, show me my mistake.
>
> As other have explained, that macro falls apart when applied to a
> pointer instead of an array. Something that can happen quite easily.
Patrick, pointers don't come into the equation here. Alla_ is simply
confusing things. Though you are correct, it's irrelevant to the
question the OP has asked.
> The thing to do in practice and if you use gcc is to use an extension
No, the thing to do in practice is usually to try to write code as
portable as practical. There are situations in which portability will
not be practical, but this is not one of those situations.
> to make sure it is really an array and not a *. Here a macro inspired
> from the one used in Linux kernel
>
> #ifdef __GNUC__
> #define NUM_ELEMS(arr) (sizeof(struct {int
> :-!!(__builtin_types_compatible_p(typeof (arr), typeof
> (&0[arr])));})+sizeof arr/sizeof 0[arr])
Didn't you notice that you've broken a macro definition up into
multiple lines without a line concatination sequence? Apparently not.
> #else
> /* A portable variant, but which doesn't check for array or pointer.
> */
> #define NUM_ELEMS(arr) (sizeof arr/sizeof 0[arr])
> #endif
Ye gads!
> 2 remarks:
> 1 the 0[arr] is just a little trick so that one doesn't need the extra
> parenthesis around the macro parameter.
This is, IMO, unnecessary obfuscation.
> 2 sizeof arr also hasn't the parenthesis, this I did to enforce that
> the MACRO is not invoked with a type but with a array name.
And if someone uses, say, an expression such as NUM_ELEMS(somearray +
2)? The expansion will be (sizeof somearray + 2/sizeof 0[somearray +
2]), a legal expression that doesn't represent the number of elements
of somearray! It parses as (sizeof somearray + (2 / sizeof 0[somearray
+ 2])).
And the 0[arr] or even arr[0] expression would produce a diagnostic if
arr were a type name.
--
----- Dig the NEW and IMPROVED news sig!! -----
-------------- Shaggy was here! ---------------
Ain't I'm a dawg!!
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Re: sizeof(x) / sizeof(x[0]) "Patrick.Schluter" <Patrick.Schluter@free.fr> - 2017-05-24 08:16 +0200
Re: sizeof(x) / sizeof(x[0]) "Peter \"Shaggy\" Haywood" <phaywood@alphalink.com.au> - 2017-05-27 17:44 +1000
Re: sizeof(x) / sizeof(x[0]) "Patrick.Schluter" <Patrick.Schluter@free.fr> - 2017-05-28 13:52 +0200
Re: sizeof(x) / sizeof(x[0]) "Peter \"Shaggy\" Haywood" <phaywood@alphalink.com.au> - 2017-06-04 18:24 +1000
csiph-web