Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #73566 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2015-10-22 11:30 -0700 |
| Last post | 2015-10-24 21:24 +0100 |
| Articles | 20 on this page of 68 — 12 participants |
Back to article view | Back to comp.lang.c
Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-22 11:30 -0700
Re: Two options of a program to find a track in the list Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-10-22 14:44 -0400
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 01:16 -0700
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 01:22 -0700
Re: Two options of a program to find a track in the list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-23 10:52 +0100
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 09:57 +0100
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 02:35 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 10:59 +0100
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 03:42 -0700
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 03:47 -0700
Re: Two options of a program to find a track in the list Barry Schwarz <schwarzb@dqel.com> - 2015-10-23 11:02 -0700
Re: Two options of a program to find a track in the list Geoff <geoff@invalid.invalid> - 2015-10-23 11:24 -0700
Re: Two options of a program to find a track in the list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-23 10:39 +0100
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 11:03 +0100
Re: Two options of a program to find a track in the list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-23 11:21 +0100
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 11:36 +0100
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 02:42 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 11:10 +0100
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 03:24 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 11:45 +0100
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 09:00 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 17:16 +0100
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 09:47 -0700
Re: Two options of a program to find a track in the list Bartc <bc@freeuk.com> - 2015-10-23 13:19 +0100
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 15:38 +0100
Re: Two options of a program to find a track in the list Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-10-23 10:57 -0400
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 15:59 +0100
Re: Two options of a program to find a track in the list David Brown <david.brown@hesbynett.no> - 2015-10-23 17:25 +0200
Re: Two options of a program to find a track in the list Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-10-23 11:55 -0400
Re: Two options of a program to find a track in the list Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2015-10-23 10:45 -0600
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 16:55 +0100
Re: Two options of a program to find a track in the list Bartc <bc@freeuk.com> - 2015-10-23 17:21 +0100
Re: Two options of a program to find a track in the list Bartc <bc@freeuk.com> - 2015-10-23 17:23 +0100
Re: Two options of a program to find a track in the list Keith Thompson <kst-u@mib.org> - 2015-10-23 12:58 -0700
Re: Two options of a program to find a track in the list Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-23 02:19 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 10:28 +0100
Re: Two options of a program to find a track in the list Bartc <bc@freeuk.com> - 2015-10-23 11:12 +0100
Re: Two options of a program to find a track in the list Keith Thompson <kst-u@mib.org> - 2015-10-23 13:42 -0700
Re: Two options of a program to find a track in the list Bartc <bc@freeuk.com> - 2015-10-23 22:14 +0100
Re: Two options of a program to find a track in the list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-23 22:28 +0100
Re: Two options of a program to find a track in the list Bartc <bc@freeuk.com> - 2015-10-23 22:47 +0100
Re: Two options of a program to find a track in the list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-23 23:21 +0100
Re: Two options of a program to find a track in the list Bartc <bc@freeuk.com> - 2015-10-24 01:37 +0100
Re: Two options of a program to find a track in the list Keith Thompson <kst-u@mib.org> - 2015-10-23 14:52 -0700
Re: Two options of a program to find a track in the list Bartc <bc@freeuk.com> - 2015-10-23 23:06 +0100
Re: Two options of a program to find a track in the list Keith Thompson <kst-u@mib.org> - 2015-10-23 16:39 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-24 21:26 +0100
Re: Two options of a program to find a track in the list Bartc <bc@freeuk.com> - 2015-10-24 22:28 +0100
Re: Two options of a program to find a track in the list Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-24 15:26 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-24 23:44 +0100
Re: Two options of a program to find a track in the list Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-10-23 09:03 -0400
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 09:10 -0700
Re: Two options of a program to find a track in the list Geoff <geoff@invalid.invalid> - 2015-10-23 11:21 -0700
Re: Two options of a program to find a track in the list Barry Schwarz <schwarzb@dqel.com> - 2015-10-22 14:50 -0700
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 01:25 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 10:00 +0100
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 01:36 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 10:04 +0100
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 03:58 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 12:07 +0100
Re: Two options of a program to find a track in the list Alla _ <modelling.data@gmail.com> - 2015-10-23 09:28 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-23 18:04 +0100
Re: Two options of a program to find a track in the list Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-10-23 13:31 -0400
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-24 21:21 +0100
Re: Two options of a program to find a track in the list Keith Thompson <kst-u@mib.org> - 2015-10-23 13:45 -0700
Re: Two options of a program to find a track in the list Ian Collins <ian-news@hotmail.com> - 2015-10-24 10:32 +1300
Re: Two options of a program to find a track in the list Keith Thompson <kst-u@mib.org> - 2015-10-23 15:33 -0700
Re: Two options of a program to find a track in the list Richard Heathfield <rjh@cpax.org.uk> - 2015-10-24 21:24 +0100
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-23 09:00 -0700 |
| Message-ID | <901f9685-b2fe-4f41-9be2-fe0b48cf05dd@googlegroups.com> |
| In reply to | #73606 |
On Friday, October 23, 2015 at 2:45:56 PM UTC+4, Richard Heathfield wrote:
> On 23/10/15 11:24, Alla _ wrote:
> > <snip>
> >
> > I am trying to understand the logic and meaning
> > of this code. One line is not clear to me:
>
> Okay.
>
> > #include <string.h>
> >
> > void terminate_at_newline(char *s)
> >
> > /** char *s is a pointer to some char variable,
>
> Right. And, since (in a string) chars occupy contiguous positions in
> memory, you can also access the chars that follow that one (if you're
> careful).
>
> > the address in memory of that
> > char variable; using this address I can access the
> > value of that variable and change it,
> > if needed **/
>
> Right.
>
> >
> > {
> > if(s != NULL) /** take into account all characters
> > except the null character, '\0'**/
>
> No. NULL is a pointer value. It means "guaranteed not to point at any
> object". We must never de-reference NULL - that is, never do '*NULL'.
>
> The code is checking to ensure that you have /not/ passed such a pointer
> value to this function because, if you have, this function can't do
> anything sensible with it.
>
> This is what we were talking about a few days ago - protecting your code
> against invalid inputs.
>
> >
> > {
> > char *t = strchr(s, '\n'); /** declare a pointer 't'
> > that finds and points to the address (location) of a character
> > 's' if this character is '\n' **/
>
> Almost. s points to the first character in a string: for example, the
> 'H' in "Hello, world!\n".
>
> strchr starts searching at that first character, and keeps searching
> until it finds either the character you're looking for ('\n') or a null
> character. If it finds the null character first, it returns a null
> POINTER, not the null character! But if it finds the '\n' first, it
> returns a pointer to that '\n' character.
>
> >
> > if(t != NULL) /** I don't understand this one; I read
> > 'if 't' isn't Null' as 't' being any character but null;
>
> No, t is a pointer. if(t != NULL) is checking that strstr actually found
> the newline (because, if it did, t won't be NULL).
>
> > how can 't' point at null, or at any other character, if 't'
> > points at the ENTER character, i.e. '\n'? **/
>
> Well, if it does point at '\n', it won't be NULL. But if there wasn't a
> '\n' character to point at, it will be NULL. Note that we spell the
> special pointer value NULL in capital letters, which helps us to
> distinguish it from another use of the word, as in "null terminating
> character".
>
> '\0' is the null terminating character. NULL is a pointer value, not a
> character.
>
> > {
> > *t = '\0'; /** if 't' is not NULL, the value at the
> > address 't' points to should be assigned the NULL value **/
>
> Almost. If t is not a null pointer (i.e. NULL), then the value at the
> address t points to should be assigned the value of a null terminating
> character.
>
> I realise that this is an unfortunate situation - that the word "null"
> should be used in two such very different situations and for very
> different reasons - but that's life.
>
> <snip>
>
> --
> Richard Heathfield
> Email: rjh at cpax dot org dot uk
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line 4 vacant - apply within
I am so happy, I got it :)))
I see what NULL means now. I've seen it so many times;
I've been many times advised here to use the test for it,
but only now I understand it: Null pointer is a pointer
that points nowhere. Thus, if(t != NULL) literally means
if 't' doesn't point anywhere at all, if 't' doesn't refer
to any address of any character.
void terminate_at_newline(char *s)
{
if(s != NULL) /**if 's' does point at any address;
could also be written as 'if (s)'
because this means 'if s is true,
which has the value bigger than zero **/
{
char *t = strchr(s, '\n');
if(t != NULL) /** same here: if 't' does point at an address
of any variable, in fact at '\n', then put '\0'
instead of '\n'**/
{
*t = '\0';
}
}
}
One more question on this:
if(t != NULL) /** same here: if 't' does point at an address
of any variable, in fact at '\n', then put '\0'
instead of '\n'**/
if 't' points at the ENTER ('\n'), and I change that
to '\0', would it produce two '\0' at the end of the string;
or if there is a '\n' at the end, then there is no '\0' before
it in the string?
Thank you!
PS smiling - I've understood something! ) Actually, read
a bit more about it, and only then understood. Still, nice.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-10-23 17:16 +0100 |
| Message-ID | <n0dmdi$b1a$1@dont-email.me> |
| In reply to | #73626 |
On 23/10/15 17:00, Alla _ wrote:
<snip>
> I am so happy, I got it :)))
Progress. :-)
> I see what NULL means now. I've seen it so many times;
> I've been many times advised here to use the test for it,
> but only now I understand it: Null pointer is a pointer
> that points nowhere. Thus, if(t != NULL) literally means
> if 't' doesn't point anywhere at all, if 't' doesn't refer
> to any address of any character.
Right. NULL is a "null pointer constant", equivalent to (void *)0 (and
is /probably/ defined like that in some of your implementation headers,
although 0 is also a legal definition. This is a pointer value, though,
not a char value.
>
> void terminate_at_newline(char *s)
>
> {
> if(s != NULL) /**if 's' does point at any address;
> could also be written as 'if (s)'
> because this means 'if s is true,
> which has the value bigger than zero **/
It could. (Well, "not equal to" rather than "bigger than".) I prefer the
!= NULL form because it clarifies that we are dealing with a pointer
value rather than a boolean value.
>
> {
> char *t = strchr(s, '\n');
>
> if(t != NULL) /** same here: if 't' does point at an address
> of any variable, in fact at '\n', then put '\0'
> instead of '\n'**/
Yes.
> {
> *t = '\0';
> }
> }
> }
>
> One more question on this:
> if(t != NULL) /** same here: if 't' does point at an address
> of any variable, in fact at '\n', then put '\0'
> instead of '\n'**/
> if 't' points at the ENTER ('\n'), and I change that
> to '\0', would it produce two '\0' at the end of the string;
The original null terminator will still be there, but a string is
defined as a contiguous sequence of characters terminated by the first
null terminating character. So the string has been shortened (but the
amount of space reserved for it has not changed).
> or if there is a '\n' at the end, then there is no '\0' before
> it in the string?
fgets will return, say, "Hello, world\n", which looks like this in memory:
'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '\n', '\0'
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-23 09:47 -0700 |
| Message-ID | <b48f914e-84dc-4d3d-a8f7-483dd24828f8@googlegroups.com> |
| In reply to | #73629 |
On Friday, October 23, 2015 at 8:17:02 PM UTC+4, Richard Heathfield wrote:
> On 23/10/15 17:00, Alla _ wrote:
>
> <snip>
>
> > I am so happy, I got it :)))
>
> Progress. :-)
>
> > I see what NULL means now. I've seen it so many times;
> > I've been many times advised here to use the test for it,
> > but only now I understand it: Null pointer is a pointer
> > that points nowhere. Thus, if(t != NULL) literally means
> > if 't' doesn't point anywhere at all, if 't' doesn't refer
> > to any address of any character.
>
> Right. NULL is a "null pointer constant", equivalent to (void *)0 (and
> is /probably/ defined like that in some of your implementation headers,
> although 0 is also a legal definition. This is a pointer value, though,
> not a char value.
>
> >
> > void terminate_at_newline(char *s)
> >
> > {
> > if(s != NULL) /**if 's' does point at any address;
> > could also be written as 'if (s)'
> > because this means 'if s is true,
> > which has the value bigger than zero **/
>
> It could. (Well, "not equal to" rather than "bigger than".) I prefer the
> != NULL form because it clarifies that we are dealing with a pointer
> value rather than a boolean value.
>
> >
> > {
> > char *t = strchr(s, '\n');
> >
> > if(t != NULL) /** same here: if 't' does point at an address
> > of any variable, in fact at '\n', then put '\0'
> > instead of '\n'**/
>
> Yes.
>
> > {
> > *t = '\0';
> > }
> > }
> > }
> >
> > One more question on this:
> > if(t != NULL) /** same here: if 't' does point at an address
> > of any variable, in fact at '\n', then put '\0'
> > instead of '\n'**/
> > if 't' points at the ENTER ('\n'), and I change that
> > to '\0', would it produce two '\0' at the end of the string;
>
> The original null terminator will still be there, but a string is
> defined as a contiguous sequence of characters terminated by the first
> null terminating character. So the string has been shortened (but the
> amount of space reserved for it has not changed).
>
> > or if there is a '\n' at the end, then there is no '\0' before
> > it in the string?
>
> fgets will return, say, "Hello, world\n", which looks like this in memory:
>
> 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '\n', '\0'
>
> --
> Richard Heathfield
> Email: rjh at cpax dot org dot uk
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line 4 vacant - apply within
Thank you! It's clear now.
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-23 13:19 +0100 |
| Message-ID | <n0d8gj$cf8$1@dont-email.me> |
| In reply to | #73588 |
On 23/10/2015 09:57, Richard Heathfield wrote: > On 23/10/15 09:16, Alla _ wrote: >> I. sizeof(all_tracks) / sizeof(all_tracks[0]); > > The parentheses are superfluous and serve no purpose at all. > > sizeof all_tracks / sizeof all_tracks[0] > > works just fine. Yet sometimes the parentheses are needed. How to remember when you need them and when you don't? Simplest is to just use them all the time. Then you also have consistent-looking code which also matches what is done with functions or macros taking an argument. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-10-23 15:38 +0100 |
| Message-ID | <n0dgkn$g2n$1@dont-email.me> |
| In reply to | #73616 |
On 23/10/15 13:19, Bartc wrote: > On 23/10/2015 09:57, Richard Heathfield wrote: >> On 23/10/15 09:16, Alla _ wrote: > >>> I. sizeof(all_tracks) / sizeof(all_tracks[0]); >> >> The parentheses are superfluous and serve no purpose at all. >> >> sizeof all_tracks / sizeof all_tracks[0] >> >> works just fine. > > Yet sometimes the parentheses are needed. Almost never, in fact. You only ever need them when using a parenthesised type as an operand, and that's almost always a bad idea. > How to remember when you need > them and when you don't? Simplest is to just use them all the time. How do you remember when you need to have a Christmas tree in your living room? Simplest is to just have one there all the time. There is a good reason *not* to use the parentheses, which is that omitting them acts to reinforce the fact that sizeof is an operator, not a function, something that is otherwise quite easy to forget. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-10-23 10:57 -0400 |
| Message-ID | <n0dho5$l94$1@dont-email.me> |
| In reply to | #73620 |
On 10/23/2015 10:38 AM, Richard Heathfield wrote:
> On 23/10/15 13:19, Bartc wrote:
>> On 23/10/2015 09:57, Richard Heathfield wrote:
>>> On 23/10/15 09:16, Alla _ wrote:
>>
>>>> I. sizeof(all_tracks) / sizeof(all_tracks[0]);
>>>
>>> The parentheses are superfluous and serve no purpose at all.
>>>
>>> sizeof all_tracks / sizeof all_tracks[0]
>>>
>>> works just fine.
>>
>> Yet sometimes the parentheses are needed.
>
> Almost never, in fact. You only ever need them when using a
> parenthesised type as an operand, and that's almost always a bad idea.
>
>> How to remember when you need
>> them and when you don't? Simplest is to just use them all the time.
>
> How do you remember when you need to have a Christmas tree in your
> living room? Simplest is to just have one there all the time.
>
> There is a good reason *not* to use the parentheses, which is that
> omitting them acts to reinforce the fact that sizeof is an operator, not
> a function, something that is otherwise quite easy to forget.
Why is the distinction important enough to be worth flaunting?
Would forgetting the distinction (whether easily or by a deliberate
act of will) have tragic consequences?
Sometimes I use the parentheses, sometimes I don't -- I go with
whatever seems more readable in the context of the moment. I also
sometimes use unnecessary parentheses elsewhere, like `x << (y + z)'
or `(a && b) || c'. The parentheses are unnecessary, but so, I think,
is chastisement for using them.
Heck, I go so far as to insert large amounts of white space in
my code, even though it's utterly unnecessary! Gonna sue me?
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-10-23 15:59 +0100 |
| Message-ID | <n0dhrs$le8$1@dont-email.me> |
| In reply to | #73621 |
On 23/10/15 15:57, Eric Sosman wrote: <snip> > Heck, I go so far as to insert large amounts of white space in > my code, even though it's utterly unnecessary! Gonna sue me? Yeah. You'd better get yourself a good lawyer. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2015-10-23 17:25 +0200 |
| Message-ID | <n0djdk$sim$1@dont-email.me> |
| In reply to | #73621 |
On 23/10/15 16:57, Eric Sosman wrote: > On 10/23/2015 10:38 AM, Richard Heathfield wrote: >> On 23/10/15 13:19, Bartc wrote: >>> On 23/10/2015 09:57, Richard Heathfield wrote: >>>> On 23/10/15 09:16, Alla _ wrote: >>> >>>>> I. sizeof(all_tracks) / sizeof(all_tracks[0]); >>>> >>>> The parentheses are superfluous and serve no purpose at all. >>>> >>>> sizeof all_tracks / sizeof all_tracks[0] >>>> >>>> works just fine. >>> >>> Yet sometimes the parentheses are needed. >> >> Almost never, in fact. You only ever need them when using a >> parenthesised type as an operand, and that's almost always a bad idea. >> >>> How to remember when you need >>> them and when you don't? Simplest is to just use them all the time. >> >> How do you remember when you need to have a Christmas tree in your >> living room? Simplest is to just have one there all the time. >> >> There is a good reason *not* to use the parentheses, which is that >> omitting them acts to reinforce the fact that sizeof is an operator, not >> a function, something that is otherwise quite easy to forget. > > Why is the distinction important enough to be worth flaunting? > Would forgetting the distinction (whether easily or by a deliberate > act of will) have tragic consequences? I would go further and say that if you are using sizeof in a way that does not work as though it were a sortof-function, or it is not obvious what it is doing despite the parentheses, then your code is probably unclear in the first place. About the only think I can think of where it really matters that sizeof is not a function is if the operand has side effects. "sizeof(a++)" does not increment "a" in the way "foo(a++)" does. Writing either "sizeof(a++)" or "sizeof a++" is, IHMO, bad code in the first place. I would even question "foo(a++)" in most cases, but I expect opinion will differ on that one. Incidentally, MISRA (the C coding standard mandated by the automotive industry in Europe, amongst others) insists that sizeof has parenthesis - it also insists on parenthesis to show operator precedence. I don't always agree with MISRA, but I agree on that one. > > Sometimes I use the parentheses, sometimes I don't -- I go with > whatever seems more readable in the context of the moment. I also > sometimes use unnecessary parentheses elsewhere, like `x << (y + z)' > or `(a && b) || c'. The parentheses are unnecessary, but so, I think, > is chastisement for using them. In those two cases, I would immediately reject code that did not have those parentheses - they may be unnecessary to a C compiler, but they are very necessary to clear coding with minimal risk of errors. > > Heck, I go so far as to insert large amounts of white space in > my code, even though it's utterly unnecessary! Gonna sue me? >
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-10-23 11:55 -0400 |
| Message-ID | <n0dl4u$519$1@dont-email.me> |
| In reply to | #73623 |
On 10/23/2015 11:25 AM, David Brown wrote:
> On 23/10/15 16:57, Eric Sosman wrote:
>> On 10/23/2015 10:38 AM, Richard Heathfield wrote:
>>>[... concerning `sizeof(thing)' vs. `sizeof thing' ...]
>>> There is a good reason *not* to use the parentheses, which is that
>>> omitting them acts to reinforce the fact that sizeof is an operator, not
>>> a function, something that is otherwise quite easy to forget.
>>
>> Why is the distinction important enough to be worth flaunting?
>> Would forgetting the distinction (whether easily or by a deliberate
>> act of will) have tragic consequences?
>
> I would go further and say that if you are using sizeof in a way that
> does not work as though it were a sortof-function, or it is not obvious
> what it is doing despite the parentheses, then your code is probably
> unclear in the first place.
>
> About the only think I can think of where it really matters that sizeof
> is not a function is if the operand has side effects. "sizeof(a++)"
> does not increment "a" in the way "foo(a++)" does. Writing either
> "sizeof(a++)" or "sizeof a++" is, IHMO, bad code in the first place. I
> would even question "foo(a++)" in most cases, but I expect opinion will
> differ on that one.
When I'm applying sizeof to a single object or to an array element,
I usually omit parentheses: `sizeof thing' or `sizeof thing[0]' seems
clear enough as it stands. But when there's a larger expression that
involves sizeof somewhere:
struct whatnot *ptr = malloc(sizeof *ptr * count);
or
if (sizeof header + payloadsize <= bufsize) { ... }
... it seems to me readability begins to suffer. Sometimes it can be
repaired by a simple rearrangement:
struct whatnot *ptr = malloc(count * sizeof *ptr);
... looks like an improvement, but doing the same in the second case
would look rather strange:
if (payloadsize + sizeof header <= bufsize) { ... }
"Waitaminnit, doesn't the payload come *after* the header? Why'd
he write it backwards?" To avoid jarring the reader, I think
if (sizeof(header) + payloadsize <= bufsize) { ... }
reads more smoothly.
De gustibus non disputandum est, of course.[*]
[*] Latin: "It's no use arguing with Gus."
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2015-10-23 10:45 -0600 |
| Message-ID | <1bziz9y1ml.fsf@pfeifferfamily.net> |
| In reply to | #73624 |
Eric Sosman <esosman@comcast-dot-net.invalid> writes:
>
> When I'm applying sizeof to a single object or to an array element,
> I usually omit parentheses: `sizeof thing' or `sizeof thing[0]' seems
> clear enough as it stands. But when there's a larger expression that
> involves sizeof somewhere:
Just to throw another option into the mix, most of the time I find it
clearer to use parentheses around the expression that includes the
sizeof operator, as in:
> struct whatnot *ptr = malloc(sizeof *ptr * count);
struct whatnot *ptr = malloc((sizeof *ptr) * count);
> or
> if (sizeof header + payloadsize <= bufsize) { ... }
if ((sizeof header) + payloadsize <= bufsize) { ... }
or
(sizeof awry) / (sizeof awry[0])
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-10-23 16:55 +0100 |
| Message-ID | <n0dl6e$57u$1@dont-email.me> |
| In reply to | #73623 |
On 23/10/15 16:25, David Brown wrote: > On 23/10/15 16:57, Eric Sosman wrote: <the sizeof vs sizeof() debate is back> >> Sometimes I use the parentheses, sometimes I don't -- I go with >> whatever seems more readable in the context of the moment. I also >> sometimes use unnecessary parentheses elsewhere, like `x << (y + z)' >> or `(a && b) || c'. The parentheses are unnecessary, but so, I think, >> is chastisement for using them. > > In those two cases, I would immediately reject code that did not have > those parentheses - they may be unnecessary to a C compiler, but they > are very necessary to clear coding with minimal risk of errors. And I would immediately reject code that did have them, unless there was some extraordinarily good reason why it was considered a good idea to use a type name. It's curious, isn't it, how two people can have such contrary views on a minor technical point? I am reminded of the two engineering students who 'fought' over whether the paper should hang in front of, or behind, the toilet roll. They agreed that they should go away and study the problem (independently) and come up with a reasoned, logical, technical comparison of the two methods and a concluding recommendation. Each did so, and - yes, that's right - each one changed his mind as a result of his analysis. And so the dispute continued, but on a new level. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-23 17:21 +0100 |
| Message-ID | <n0dmma$c6l$1@dont-email.me> |
| In reply to | #73620 |
On 23/10/2015 15:38, Richard Heathfield wrote: > On 23/10/15 13:19, Bartc wrote: >> On 23/10/2015 09:57, Richard Heathfield wrote: >>> On 23/10/15 09:16, Alla _ wrote: >> >>>> I. sizeof(all_tracks) / sizeof(all_tracks[0]); >>> >>> The parentheses are superfluous and serve no purpose at all. >>> >>> sizeof all_tracks / sizeof all_tracks[0] >>> >>> works just fine. >> >> Yet sometimes the parentheses are needed. > > Almost never, in fact. You only ever need them when using a > parenthesised type as an operand, and that's almost always a bad idea. Obtaining the size of a type is useful in plenty of situations where you don't want to create an object of that type just for the purpose. >> How to remember when you need >> them and when you don't? Simplest is to just use them all the time. > How do you remember when you need to have a Christmas tree in your > living room? Simplest is to just have one there all the time. Christmas I don't have a problem with. Remembering whether it is expressions or types that need the obligatory parentheses, I do. But I also think it looks better with them. > There is a good reason *not* to use the parentheses, which is that > omitting them acts to reinforce the fact that sizeof is an operator, not > a function, something that is otherwise quite easy to forget. What would happen if you did forget and used it as an operator? -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-23 17:23 +0100 |
| Message-ID | <n0dmqv$c6l$2@dont-email.me> |
| In reply to | #73630 |
On 23/10/2015 17:21, Bartc wrote: >> There is a good reason *not* to use the parentheses, which is that >> omitting them acts to reinforce the fact that sizeof is an operator, not >> a function, something that is otherwise quite easy to forget. > > What would happen if you did forget and used it as an operator? Or rather, a function? See, I don't really care one way or another. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-10-23 12:58 -0700 |
| Message-ID | <lnziz9uzjx.fsf@kst-u.example.com> |
| In reply to | #73588 |
Richard Heathfield <rjh@cpax.org.uk> writes:
> On 23/10/15 09:16, Alla _ wrote:
[...]
>> 1) I know that sizeof computes the amount of bytes,
>> and includes a terminating null character;
>
> Well, it includes the whole object. It doesn't care what value that
> object has. Null terminating characters are irrelevant to sizeof.
That is 100% correct, but I'm going to show a case where it might not
quite seem that way.
char str[] = "hello";
sizeof str == 6, and that includes the 5 characters of "hello" plus the
terminating '\0' character. That's because when you define an array
object without specifying the size, the size is determined by the
initializer, and in this case the size of the initializer is the size of
the string, which includes the terminating '\0'.
The above is exactly equivalent to:
char str[6] = "hello";
We're just letting the compiler fill in the 6 for us.
But the fact that str[5] happens to be '\0' doesn't affect how sizeof
works. Once you've initialized str, you can change it:
char str[] = "hello";
str[0] = '0';
str[1] = '1';
str[2] = '2';
str[3] = '3';
str[4] = '4';
str[5] = '5';
I've changed the contents of the array object str, but not its size.
After the assignment, str no longer contains a string, because
I've clobbered the terminating '\0'. When I evaluate `sizeof str`,
I still get 6.
The thing to remember is that a string is not an array. Rather, an
array may (or may not) *contain* a string. A "string" in C is a data
format, not a data type. (There are languages other than C where
that might not be the case, but we're only talking about C here.)
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-10-23 02:19 -0700 |
| Message-ID | <1634ce55-e6c6-411f-89aa-441a284a7e5c@googlegroups.com> |
| In reply to | #73584 |
On Friday, October 23, 2015 at 9:16:39 AM UTC+1, Alla _ wrote:
>
> 1) I know that sizeof computes the amount of bytes,
> and includes a terminating null character; hence, when
> it returns, for example, 9, it means that there are 8
> characters + the null character. How does 9 fits into
> later computations; does the machine understand that
> the length (the amount) of entries is actually 8 characters
> + the null character?
>
Its wrong to think of it like that.
sizeof() gives the size of an object in memory, either a type (which
in my view is the best way to use it, e.g. sizeof(int) will give the
size of an int, on your machine, in bytes. Or you can pass it an
object.
int x;
sizeof(x); // now we have the size of x.
However C strings are an arrangement of bytes in memory
F r e d d e a d '0'
nine bytes. but if we're using a buffer to store several strings,
its unlikely that all of them will be exactly 8 characters. sizeof
gives the size of the buffer, not the string that happens to be in
it. When you hard code a string literal
sizeof("Freddead");
the buffer and the string become the same, but it's rare to want
to do that.
So strlen() gives you the number of characters in a string. It's a
runtime function, unlike sizeof()
>
> 2) Also, I don't understand how
> sizeof(all_tracks) / sizeof(all_tracks[0]);
> works with a matrix.
>
No, I don't either. It depends how the matrix is set up in memory.
The code will break if all_tracks is moved to dynamic memory, for
instance.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-10-23 10:28 +0100 |
| Message-ID | <n0cug9$7r9$1@dont-email.me> |
| In reply to | #73591 |
On 23/10/15 10:19, Malcolm McLean wrote: > On Friday, October 23, 2015 at 9:16:39 AM UTC+1, Alla _ wrote: >> >> 1) I know that sizeof computes the amount of bytes, >> and includes a terminating null character; hence, when >> it returns, for example, 9, it means that there are 8 >> characters + the null character. How does 9 fits into >> later computations; does the machine understand that >> the length (the amount) of entries is actually 8 characters >> + the null character? >> > Its wrong to think of it like that. > sizeof() gives the size of an object in memory, either a type (which > in my view is the best way to use it You won't be surprised to hear that I disagree! :-) Almost always, the reason for finding a size is that you have something (i.e. an object) that you want to know the size of, so cut out the middle man. This has the pleasant side-effect that, if you later decide that you want to change the type (eg change x from a foo to a bar) that you don't have to hunt through all your sizeof(foo) and decide which of them needs to change to sizeof(bar). <snip> >> 2) Also, I don't understand how >> sizeof(all_tracks) / sizeof(all_tracks[0]); >> works with a matrix. >> > No, I don't either. It depends how the matrix is set up in memory. Well, we know how it's set up in memory. It's an array of char arrays. > The code will break if all_tracks is moved to dynamic memory, for > instance. That's like complaining that you won't be able to steer trains if you run them on roads instead of rails. When you make significant changes to the way data is organised, you can expect to have to make significant changes to the way you manage that data. The sizeof arr / sizeof arr[0] idiom is an important technique for statically (that is, not dynamically!) allocated arrays. That it does not apply to dynamically allocated arrays does not mean it is not useful for statically (that is, not dynamically) allocated arrays. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-23 11:12 +0100 |
| Message-ID | <n0d128$h3h$1@dont-email.me> |
| In reply to | #73584 |
On 23/10/2015 09:16, Alla _ wrote:
> <snip>
>
> Thank you for your reply. I have few questions.
>
> I. sizeof(all_tracks) / sizeof(all_tracks[0]);
>
> how does sizeof work with all_tracks, which have a matrix form?
>
> 1) I know that sizeof computes the amount of bytes,
> and includes a terminating null character; hence, when
> it returns, for example, 9, it means that there are 8
> characters + the null character. How does 9 fits into
> later computations; does the machine understand that
> the length (the amount) of entries is actually 8 characters
> + the null character?
>
> 2) Also, I don't understand how
> sizeof(all_tracks) / sizeof(all_tracks[0]);
> works with a matrix.
It confuses me too. But I wrote this code which shows all the various
possibilities and might make it clear what sizeof() and strlen() mean in
different contexts:
#include <stdio.h>
#include <string.h>
#define SHOWSIZE(A) printf("SIZE: %s: %d bytes\n",#A,sizeof(A));
#define SHOWLENGTH(A) \
printf("LENGTH: %s: %d elements\n",\
#A,sizeof(A)/sizeof(A[0]));
#define SHOWSTRINGLENGTH(A) \
printf("STRINGLENGTH: %s: %d \"%s\" characters\n",\
#A,strlen(A),A);
char all_tracks[][80] = {
"I left my heart in Harvard Med School", //0
"Newark, Newark - a wonderful town", //1
"Dancing with a Dork", //2
"From here to maternity", //3
"The girl from Iwo Jima"}; //4
int main(void) {
SHOWSIZE(all_tracks);
puts("");
SHOWLENGTH(all_tracks);
SHOWLENGTH(all_tracks[0]);
SHOWLENGTH(all_tracks[1]);
SHOWLENGTH(all_tracks[2]);
SHOWLENGTH(all_tracks[3]);
SHOWLENGTH(all_tracks[4]);
puts("");
SHOWSTRINGLENGTH(all_tracks[0]);
SHOWSTRINGLENGTH(all_tracks[1]);
SHOWSTRINGLENGTH(all_tracks[2]);
SHOWSTRINGLENGTH(all_tracks[3]);
SHOWSTRINGLENGTH(all_tracks[4]);
}
Don't try and understand the #defines; they're just to make the main
code less cluttered. When you run it, it will show how the various sizes
and lengths click into place.
Note that for this data, SHOWSIZE(all_tracks[2]) and
SHOWLENGTH(all_tracks[2]) would give the same value: 80 bytes or 80
elements, and the element size is a single byte or char.
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-10-23 13:42 -0700 |
| Message-ID | <lnvb9xuxjj.fsf@kst-u.example.com> |
| In reply to | #73600 |
Bartc <bc@freeuk.com> writes:
[...]
> #define SHOWSIZE(A) printf("SIZE: %s: %d bytes\n",#A,sizeof(A));
[...]
That %d should be %zu.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-23 22:14 +0100 |
| Message-ID | <n0e7si$qcj$1@dont-email.me> |
| In reply to | #73651 |
On 23/10/2015 21:42, Keith Thompson wrote:
> Bartc <bc@freeuk.com> writes:
> [...]
>> #define SHOWSIZE(A) printf("SIZE: %s: %d bytes\n",#A,sizeof(A));
> [...]
>
> That %d should be %zu.
You need to complain to my compiler. Only two C compilers out of 6 said
anything. The default one I use didn't.
(Personally I don't even want to be bothered to have to put in "%d".)
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-10-23 22:28 +0100 |
| Message-ID | <87egglnuk2.fsf@bsb.me.uk> |
| In reply to | #73654 |
Bartc <bc@freeuk.com> writes:
> On 23/10/2015 21:42, Keith Thompson wrote:
>> Bartc <bc@freeuk.com> writes:
>> [...]
>>> #define SHOWSIZE(A) printf("SIZE: %s: %d bytes\n",#A,sizeof(A));
>> [...]
>>
>> That %d should be %zu.
>
> You need to complain to my compiler. Only two C compilers out of 6
> said anything. The default one I use didn't.
Surely you are the appropriate person to complain if a compiler misses
an error you'd like to have diagnosed? (I'm assuming you don't
mean "I don't care" which was my first reading of what you wrote.)
> (Personally I don't even want to be bothered to have to put in "%d".)
You might like the way Go does it.
--
Ben.
[toc] | [prev] | [next] | [standalone]
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web