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


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

setting pointers to NULL and testing question.

Started byG G <gdotone@gmail.com>
First post2016-06-12 16:21 -0700
Last post2016-06-16 21:39 -0700
Articles 20 on this page of 86 — 20 participants

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


Contents

  setting pointers to NULL and testing question. G G <gdotone@gmail.com> - 2016-06-12 16:21 -0700
    Re: setting pointers to NULL and testing question. Richard Heathfield <rjh@cpax.org.uk> - 2016-06-13 00:50 +0100
      Re: setting pointers to NULL and testing question. G G <gdotone@gmail.com> - 2016-06-12 17:03 -0700
      Re: setting pointers to NULL and testing question. Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-06-12 20:25 -0600
        Re: setting pointers to NULL and testing question. James Kuyper <jameskuyper@verizon.net> - 2016-06-12 22:57 -0400
          Re: setting pointers to NULL and testing question. Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-06-13 10:03 -0600
            Re: setting pointers to NULL and testing question. Tim Rentsch <txr@alumni.caltech.edu> - 2016-06-15 14:43 -0700
        Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-13 08:06 -0700
          Re: setting pointers to NULL and testing question. Richard Damon <Richard@Damon-Family.org> - 2016-06-16 08:27 -0400
            Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-16 06:27 -0700
              Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-16 07:31 -0700
              Re: setting pointers to NULL and testing question. Richard Damon <Richard@Damon-Family.org> - 2016-06-18 13:39 -0400
                Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-18 11:37 -0700
                  Re: setting pointers to NULL and testing question. Richard Damon <Richard@Damon-Family.org> - 2016-06-18 17:17 -0400
                    Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-18 17:22 -0700
        Re: setting pointers to NULL and testing question. James Kuyper <jameskuyper@verizon.net> - 2016-06-13 14:10 -0400
          Re: setting pointers to NULL and testing question. Keith Thompson <kst-u@mib.org> - 2016-06-13 11:28 -0700
          Re: setting pointers to NULL and testing question. Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2016-06-13 12:31 -0600
      Re: setting pointers to NULL and testing question. Keith Thompson <kst-u@mib.org> - 2016-06-12 19:38 -0700
        Re: setting pointers to NULL and testing question. Richard Heathfield <rjh@cpax.org.uk> - 2016-06-13 07:35 +0100
      Re: setting pointers to NULL and testing question. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-06-13 11:40 +0100
        Re: setting pointers to NULL and testing question. BartC <bc@freeuk.com> - 2016-06-13 11:56 +0100
          Re: setting pointers to NULL and testing question. Martin Shobe <mashobe9@gmail.com> - 2016-06-13 06:22 -0500
            Re: setting pointers to NULL and testing question. BartC <bc@freeuk.com> - 2016-06-13 12:39 +0100
              Re: setting pointers to NULL and testing question. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-06-13 15:22 +0100
                Re: setting pointers to NULL and testing question. BartC <bc@freeuk.com> - 2016-06-13 17:34 +0100
                  Re: setting pointers to NULL and testing question. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-06-13 19:31 +0100
                    Re: setting pointers to NULL and testing question. BartC <bc@freeuk.com> - 2016-06-13 20:17 +0100
                      Re: setting pointers to NULL and testing question. Keith Thompson <kst-u@mib.org> - 2016-06-13 12:47 -0700
                        Re: setting pointers to NULL and testing question. Tim Rentsch <txr@alumni.caltech.edu> - 2016-06-15 16:44 -0700
                          Re: setting pointers to NULL and testing question. Keith Thompson <kst-u@mib.org> - 2016-06-15 17:20 -0700
        Re: setting pointers to NULL and testing question. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-06-13 04:01 -0700
          Re: setting pointers to NULL and testing question. Tim Rentsch <txr@alumni.caltech.edu> - 2016-06-16 12:57 -0700
        Re: setting pointers to NULL and testing question. Richard Heathfield <rjh@cpax.org.uk> - 2016-06-13 12:18 +0100
          Re: setting pointers to NULL and testing question. David Brown <david.brown@hesbynett.no> - 2016-06-13 14:01 +0200
            Re: setting pointers to NULL and testing question. Richard Heathfield <rjh@cpax.org.uk> - 2016-06-13 14:15 +0100
              Re: setting pointers to NULL and testing question. David Brown <david.brown@hesbynett.no> - 2016-06-13 15:37 +0200
                Re: setting pointers to NULL and testing question. Richard Heathfield <rjh@cpax.org.uk> - 2016-06-13 14:48 +0100
          Re: setting pointers to NULL and testing question. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-06-13 15:43 +0100
    Re: setting pointers to NULL and testing question. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-06-12 17:54 -0700
    Re: setting pointers to NULL and testing question. John Bode <jfbode1029@gmail.com> - 2016-06-14 08:36 -0700
      Re: setting pointers to NULL and testing question. Richard Heathfield <rjh@cpax.org.uk> - 2016-06-14 16:41 +0100
      Re: setting pointers to NULL and testing question. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-06-14 09:01 -0700
      Re: setting pointers to NULL and testing question. "James R. Kuyper" <jameskuyper@verizon.net> - 2016-06-14 13:25 -0400
        Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-14 10:48 -0700
          Re: setting pointers to NULL and testing question. Ian Collins <ian-news@hotmail.com> - 2016-06-15 08:24 +1200
            Re: setting pointers to NULL and testing question. "James R. Kuyper" <jameskuyper@verizon.net> - 2016-06-14 16:57 -0400
              Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-14 14:29 -0700
                Re: setting pointers to NULL and testing question. BartC <bc@freeuk.com> - 2016-06-14 22:41 +0100
                  Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-14 15:16 -0700
                    Re: setting pointers to NULL and testing question. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-06-15 00:25 +0100
                      Re: setting pointers to NULL and testing question. Keith Thompson <kst-u@mib.org> - 2016-06-14 16:58 -0700
                      Re: setting pointers to NULL and testing question. David Brown <david.brown@hesbynett.no> - 2016-06-15 09:28 +0200
                        Re: setting pointers to NULL and testing question. Keith Thompson <kst-u@mib.org> - 2016-06-15 09:57 -0700
                Re: setting pointers to NULL and testing question. David Brown <david.brown@hesbynett.no> - 2016-06-15 09:23 +0200
                  Re: setting pointers to NULL and testing question. Richard Heathfield <rjh@cpax.org.uk> - 2016-06-15 08:35 +0100
                    Re: setting pointers to NULL and testing question. Richard Heathfield <rjh@cpax.org.uk> - 2016-06-15 08:37 +0100
                    Re: setting pointers to NULL and testing question. David Brown <david.brown@hesbynett.no> - 2016-06-15 10:42 +0200
                      Re: setting pointers to NULL and testing question. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-06-15 13:28 +0100
                  Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-15 11:41 -0700
                  Re: setting pointers to NULL and testing question. raltbos@xs4all.nl (Richard Bos) - 2016-06-15 19:43 +0000
                    Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-15 13:09 -0700
                    Re: setting pointers to NULL and testing question. David Brown <david.brown@hesbynett.no> - 2016-06-15 22:31 +0200
                    Re: setting pointers to NULL and testing question. Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-06-15 17:11 -0400
                      Re: setting pointers to NULL and testing question. raltbos@xs4all.nl (Richard Bos) - 2016-06-18 20:44 +0000
                        Re: setting pointers to NULL and testing question. Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-06-18 17:20 -0400
          Re: setting pointers to NULL and testing question. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-06-14 23:22 -0700
            Re: setting pointers to NULL and testing question. Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-06-15 13:23 +0100
        Re: setting pointers to NULL and testing question. John Bode <jfbode1029@gmail.com> - 2016-06-20 13:36 -0700
      Re: setting pointers to NULL and testing question. Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-06-14 14:59 -0400
        Re: setting pointers to NULL and testing question. "James R. Kuyper" <jameskuyper@verizon.net> - 2016-06-14 15:17 -0400
        Re: setting pointers to NULL and testing question. Richard Heathfield <rjh@cpax.org.uk> - 2016-06-14 20:25 +0100
        Re: setting pointers to NULL and testing question. Tim Rentsch <txr@alumni.caltech.edu> - 2016-06-15 19:48 -0700
          Re: setting pointers to NULL and testing question. Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-06-15 23:25 -0400
            Re: setting pointers to NULL and testing question. James Kuyper <jameskuyper@verizon.net> - 2016-06-16 12:11 -0400
              Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-16 09:25 -0700
              Re: setting pointers to NULL and testing question. Tim Rentsch <txr@alumni.caltech.edu> - 2016-06-16 21:46 -0700
                Re: setting pointers to NULL and testing question. Gareth Owen <gwowen@gmail.com> - 2016-06-17 06:13 +0100
                  Re: setting pointers to NULL and testing question. Robert Wessel <robertwessel2@yahoo.com> - 2016-06-17 02:03 -0500
                    Re: setting pointers to NULL and testing question. Martin Shobe <mashobe9@gmail.com> - 2016-06-17 07:07 -0500
                  Re: setting pointers to NULL and testing question. supercat@casperkitty.com - 2016-06-17 03:18 -0700
                  Re: setting pointers to NULL and testing question. James Kuyper <jameskuyper@verizon.net> - 2016-06-17 09:16 -0400
                    Re: setting pointers to NULL and testing question. Tim Rentsch <txr@alumni.caltech.edu> - 2016-06-21 11:03 -0700
                  Re: setting pointers to NULL and testing question. Tim Rentsch <txr@alumni.caltech.edu> - 2016-06-21 10:58 -0700
                Re: setting pointers to NULL and testing question. Keith Thompson <kst-u@mib.org> - 2016-06-21 11:28 -0700
            Re: setting pointers to NULL and testing question. Tim Rentsch <txr@alumni.caltech.edu> - 2016-06-16 21:39 -0700

Page 4 of 5 — ← Prev page 1 2 3 [4] 5  Next page →


#89197

Fromraltbos@xs4all.nl (Richard Bos)
Date2016-06-15 19:43 +0000
Message-ID<5761ae6f.6916500@news.xs4all.nl>
In reply to#89136
David Brown <david.brown@hesbynett.no> wrote:

> The neatest way would be to simply allow
> 
>      double dx = monster.x-player.x;
>      double dy = monster.y-player.y
>      double monster_distance = sqrt(dx*dx+dy*dy);
>      ...
>      double dx = shot.x-player.x;
>      double dy = shot.y-player.y
>      double shot_distance = sqrt(dx*dx+dy*dy);
> 
> and say that a re-definition of "double dx" creates a new variable in a
> new scope, just as if the second part were inside its own block.

Ah, but then you'd get people wanting to make the second set of dx/dy a
different type from the first. So you'd have to allow that. And _then_
you'd get people complaining about how that is type-unsafe and
confusing. And in any case, this would only create a new scope where the
new variables are needed, _not_ end the old scope where the old
variables aren't needed any more, which is what was wanted, really.

You'd have to create a new statement, instead: an undeclare statement.
It should work much like #undef does for #define. Then you could do:

  double dx = monster.x-player.x;
  double dy = monster.y-player.y
  double monster_distance = sqrt(dx*dx+dy*dy);
  undeclare dx, dy;
  ...
  /* Note that you cannot use dx and dy here; it's as if
     they'd never been declared in the first place. */
  ...
  long int dx = shot.x-player.x;
  long int dy = shot.y-player.y
  long int shot_distance = sqrt(dx*dx+dy*dy);
  undeclare dx, dy;

and everybody would be happy *flashes most naive smile ever*.

Richard

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


#89198

Fromsupercat@casperkitty.com
Date2016-06-15 13:09 -0700
Message-ID<9f569cb2-c760-4d5a-9400-4ddc95d8b64e@googlegroups.com>
In reply to#89197
On Wednesday, June 15, 2016 at 2:44:01 PM UTC-5, Richard Bos wrote:
> You'd have to create a new statement, instead: an undeclare statement.
> It should work much like #undef does for #define. Then you could do:

A variation I've seen in some assemblers would be to say that labels
which start with some magic indicator (@@ in the case of Turbo Assembler,
if I recall) will behave as though that marker were replaced by a count
which starts at 00 and increases every time a local area boundary is
encountered, so that any references to a label within a local area
can only identify labels declared within that same area.

I'm not sure how one could best integrate the marker and area boundaries
in C syntax, but they could perhaps be taken care of in the preprocessor
using an approach very much like the Turbo Assembler approach.

If there were a directive to indicate what special character to use (to
allow for the fact that some character sets might not have a at-sign)
the preprocessor could say that symbols which start with @ will have that
@ replaced by something like __CTSYM_123, where the 123 is incremented
every time some other preprocessor directive is encountered.

Thus,

   @@@
    int @dx = monster.x-player.x;
    int @dy = monster.y-player.y;
    monster_dist = sqrt(@dx*@dx+@dy*@dy);
   @@@

with the @@@ acting as "bump the counter" directives [the fact that
bumping the counter before and after such a section would make it increase
twice as fast really shouldn't be an issue].

Another approach would be to allow a special form of declaration which
would specify that something declared within an inner block should be
joined into the outer-block scope when the inner block ends (with a
compiler-enforced requirement that such a thing must not already exist
there, and that all code paths must result in the same declarations
being made visible).

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


#89201

FromDavid Brown <david.brown@hesbynett.no>
Date2016-06-15 22:31 +0200
Message-ID<njsdvg$i86$1@dont-email.me>
In reply to#89197
On 15/06/16 21:43, Richard Bos wrote:
> David Brown <david.brown@hesbynett.no> wrote:
>
>> The neatest way would be to simply allow
>>
>>       double dx = monster.x-player.x;
>>       double dy = monster.y-player.y
>>       double monster_distance = sqrt(dx*dx+dy*dy);
>>       ...
>>       double dx = shot.x-player.x;
>>       double dy = shot.y-player.y
>>       double shot_distance = sqrt(dx*dx+dy*dy);
>>
>> and say that a re-definition of "double dx" creates a new variable in a
>> new scope, just as if the second part were inside its own block.
>
> Ah, but then you'd get people wanting to make the second set of dx/dy a
> different type from the first. So you'd have to allow that. And _then_
> you'd get people complaining about how that is type-unsafe and
> confusing. And in any case, this would only create a new scope where the
> new variables are needed, _not_ end the old scope where the old
> variables aren't needed any more, which is what was wanted, really.
>

You can, I think, pretend that whenever you see a definition such as 
"double dx = ...", that there is a new block scope started just before 
it, and which exits at the end of the current block scope.  Then your 
new "double dx" can be of any type you want.  The previous "dx" is still 
alive, and still in scope - but it is hidden (shadowed) by the new one. 
  It is up to the compiler to realise that it can optimise on that basis.

> You'd have to create a new statement, instead: an undeclare statement.
> It should work much like #undef does for #define. Then you could do:
>
>    double dx = monster.x-player.x;
>    double dy = monster.y-player.y
>    double monster_distance = sqrt(dx*dx+dy*dy);
>    undeclare dx, dy;
>    ...
>    /* Note that you cannot use dx and dy here; it's as if
>       they'd never been declared in the first place. */
>    ...
>    long int dx = shot.x-player.x;
>    long int dy = shot.y-player.y
>    long int shot_distance = sqrt(dx*dx+dy*dy);
>    undeclare dx, dy;
>
> and everybody would be happy *flashes most naive smile ever*.
>

An "undeclare" statement would be a fine idea, and give exact control 
over scopes.  But I suspect that it would be very rarely useful in practice.


> Richard
>

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


#89208

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-06-15 17:11 -0400
Message-ID<njsg9p$pnv$1@dont-email.me>
In reply to#89197
On 6/15/2016 3:43 PM, Richard Bos wrote:
>[...]
> You'd have to create a new statement, instead: an undeclare statement.
> [...]

     C already has that, for at least some scopes.  It's spelled

	}

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

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


#89567

Fromraltbos@xs4all.nl (Richard Bos)
Date2016-06-18 20:44 +0000
Message-ID<5765b284.31868296@news.xs4all.nl>
In reply to#89208
Eric Sosman <esosman@comcast-dot-net.invalid> wrote:

> On 6/15/2016 3:43 PM, Richard Bos wrote:
> >[...]
> > You'd have to create a new statement, instead: an undeclare statement.
> > [...]
> 
>      C already has that, for at least some scopes.  It's spelled
> 
> 	}

Unfortunately, that doesn't work in exactly the case under discussion.

Richard

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


#89571

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-06-18 17:20 -0400
Message-ID<nk4du5$s79$1@dont-email.me>
In reply to#89567
On 6/18/2016 4:44 PM, Richard Bos wrote:
> Eric Sosman <esosman@comcast-dot-net.invalid> wrote:
>
>> On 6/15/2016 3:43 PM, Richard Bos wrote:
>>> [...]
>>> You'd have to create a new statement, instead: an undeclare statement.
>>> [...]
>>
>>      C already has that, for at least some scopes.  It's spelled
>>
>> 	}
>
> Unfortunately, that doesn't work in exactly the case under discussion.

... and everybody is happy *flashes most naive smile ever*.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

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


#89131

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2016-06-14 23:22 -0700
Message-ID<e3e397e0-b77a-496b-b900-7cec581a9725@googlegroups.com>
In reply to#89082
On Tuesday, June 14, 2016 at 6:48:52 PM UTC+1, supe...@casperkitty.com wrote:
>
> It's too bad that most languages require all scopes to be strictly
> nested, since there are many situations where the useful lifetime 
> of some variables will end precisely at the point when their value 
> is used in computing the initial/only value of another variable which
> will never be modified during its lifetime.
>
Yes, the pattern

int foo(args ...)
{
   int answer = 0;

   /* lots of code */

   return answer;
}

void bar()
{
   const int avalue = foo( x, y, z);

   /* lots of code */ 
}

is an extremely common one.

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


#89164

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-06-15 13:23 +0100
Message-ID<877fdqy72a.fsf@bsb.me.uk>
In reply to#89131
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:

> On Tuesday, June 14, 2016 at 6:48:52 PM UTC+1, supe...@casperkitty.com wrote:
>>
>> It's too bad that most languages require all scopes to be strictly
>> nested, since there are many situations where the useful lifetime 
>> of some variables will end precisely at the point when their value 
>> is used in computing the initial/only value of another variable which
>> will never be modified during its lifetime.
>>
> Yes, the pattern
>
> int foo(args ...)
> {
>    int answer = 0;
>
>    /* lots of code */
>
>    return answer;
> }
>
> void bar()
> {
>    const int avalue = foo( x, y, z);
>
>    /* lots of code */ 
> }
>
> is an extremely common one.

And valid in C which has nested scopes, so how is it an example of the
value of allowing non-nested scopes?

-- 
Ben.

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


#89670

FromJohn Bode <jfbode1029@gmail.com>
Date2016-06-20 13:36 -0700
Message-ID<9b4b738a-b490-4ee3-a498-8dce42d033b2@googlegroups.com>
In reply to#89081
On Tuesday, June 14, 2016 at 12:26:07 PM UTC-5, James R. Kuyper wrote:
> On 06/14/2016 11:36 AM, John Bode wrote:
> > On Sunday, June 12, 2016 at 6:21:40 PM UTC-5, G G wrote:
> >> when should a pointer to set to NULL and test whether
> >> it is NULL?
> > 
> > In a non-static declaration, a pointer variable should always be initialized
> > explicitly to NULL or to a valid pointer value:
> > 
> >     T *p1 = NULL;
> >     T *p2 = &some_other_T_object;
> >     T *p3 = malloc( sizeof *p3 * number_of_elements );
> >     const char *prompt = "This is a prompt";
> > 
> > If no explicit initializer is present, the initial value of the variable
> > will be *indeterminate* (a random bit string that most likely won't 
> > correspond to NULL *or* a valid memory address) *unless* the variable is
> > declared at file scope (outside the body of any function) or with the
> > "static" keyword; in that case, the initial value will be NULL.
> 
> One caveat: Consider code such as the following:
> 
> T *p4 = NULL;
> 
> while(some_condition)
> {
>       // Many lines of code
> 
>       p4[n] = expression;
> 
>       // many more lines of code
> 
>       free(p4);
>       p4 = malloc(desired_count * sizeof *p4);
>       if(p4 == NULL)
>       {
>            // error handling
>       }
> 
>       // even more lines of code
> }
> 
> When preceded by appropriate startup code, and followed by appropriate
> follow-up code, it can be a perfectly reasonable to write a loop like
> this. However, it has not been preceded by the right startup code. If p4
> had not been initialized, many compilers will warn you about the fact
> that your code attempts to use an uninitialized value. With the NULL
> initialization, you have disabled that warning.
> 
> My own personal criterion is to declare every variable with the smallest
> scope that allows it to do the job that it needs to do. Then, if it can
> be initialized at the point of declaration with a value that I intend to
> use, I will do so. Otherwise, I will deliberately leave it uninitialized
> until I can assign it such a value, thereby enabling the compiler
> warning if I forget to create such an assignment.
> 

I agree that a pointer variable's scope and lifetime (actually, *any* 
variable's scope and lifetime) should be limited as much as possible, 
and that the declaration should be deferred until it can be initialized 
with an actual pointer value.  That is, instead of writing:

    T *p = NULL;
    // code
    p = malloc( ... );

you should write

    // code
    T *p = malloc( ... );

Sometimes I forget it's been 15 years since C99 was ratified, and I slip
into old habits.  

> 
> > A pointer variable should be set to NULL as soon as the thing it pointed to
> > ceases to exist or is no longer being used (e.g., you call free() on a
> > pointer value obtained from malloc()):
> > 
> >     T *ptr = malloc( sizeof *ptr * number_of_elements );
> >     /**
> >      * do stuff with ptr
> >      */
> >     free( ptr ); // deallocates storage obtained through malloc
> >     ptr = NULL;
> 
> I also disagree with this advice in some circumstances:
> 
>       if(condition)
>       {
>            T *ptr = malloc( sizeof *ptr * number_of_elements );
>            if(ptr)
>            {
>                /* do stuff with ptr */
>                free( ptr );
>                ptr = NULL;
>            }
>       }
> 
> Because the scope of ptr is ending, there's no need to set it to NULL.
> Granted, any decent compiler will optimize away ptr = NULL - but for
> precisely that reason, many of the better compilers will warn you
> "statement has no effect". I save my time, and the compiler's, by not
> bothering to write such assignments in the first place.
> 

Agreed.  Again, I'm thinking about pointer variables whose lifetime exceeds
that of the thing they're pointing to, although like above we should strive
to avoid that kind of situation.

> > You should test against NULL before dereferencing a pointer when 
> > 
> >     * obtaining a pointer value from any library function that can
> >       potentially return NULL, including but not limited to malloc(),
> >       realloc(), strtok(), strchr(), fopen(), etc.:
> > 
> >       FILE *fp = fopen( "some_file", "r" );
> >       if ( !fp ) // or fp == NULL
> >       {
> >         fprintf( stderr, "Could not open some_file, exiting...\n" );
> >         exit( EXIT_FAILURE );
> >       }
> > 
> >     * receiving a pointer value as a function argument without any
> >       guarantee that it's valid:
> > 
> >       void foo( void *data )
> >       {
> >         if ( !data )
> >         {
> >           // NULL input argument
> >           return;
> >         }
> > 
> >         // proceed as normal
> >       }
> 
> I agree with this advice completely. 

Yay, not a complete shutout! :-)

>                                       I personally only trust pointers
> passed to my functions if they were passed there by other functions in
> the same translation unit, or were returned by standard library
> functions that were called with arguments that guarantee a non-NULL
> value. All other pointers are checked against NULL.
> 
> Since I have to check pointer arguments for null values anyway, I try to
> design my functions so that a null value has some well-defined meaning,
> rather than being an error condition. Usually, that well-defined meaning
> is to turn off that portion of the function's behavior that would
> otherwise be associated with whatever that pointer is supposed to point
> at. Obviously, this is not appropriate for arguments that are involved
> in every aspect of the function's behavior.

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


#89084

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-06-14 14:59 -0400
Message-ID<njpk7n$78g$1@dont-email.me>
In reply to#89075
On 6/14/2016 11:36 AM, John Bode wrote:
> On Sunday, June 12, 2016 at 6:21:40 PM UTC-5, G G wrote:
>> when should a pointer to set to NULL and test whether
>> it is NULL?
>
> In a non-static declaration, a pointer variable should always be initialized
> explicitly to NULL or to a valid pointer value:
>[...]

     The arguments both for and against this practice are, I think,
too well-known to bear yet another repetition.  But here, perhaps,
may be a slightly different slant: If universal initialization is
good for pointers, why not for ints and doubles and struct tm's
and every other kind of variable?

	char buff[SIZE]  /* = {0} ? */;
	if (fgets(buff, sizeof buff, stream) != NULL) ...

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

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


#89085

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-06-14 15:17 -0400
Message-ID<e926912b-def2-e87d-7dc8-00e6c185afae@verizon.net>
In reply to#89084
On 06/14/2016 02:59 PM, Eric Sosman wrote:
> On 6/14/2016 11:36 AM, John Bode wrote:
>> On Sunday, June 12, 2016 at 6:21:40 PM UTC-5, G G wrote:
>>> when should a pointer to set to NULL and test whether
>>> it is NULL?
>>
>> In a non-static declaration, a pointer variable should always be initialized
>> explicitly to NULL or to a valid pointer value:
>> [...]
> 
>      The arguments both for and against this practice are, I think,
> too well-known to bear yet another repetition.  But here, perhaps,
> may be a slightly different slant: If universal initialization is
> good for pointers, why not for ints and doubles and struct tm's
> and every other kind of variable?
> 
> 	char buff[SIZE]  /* = {0} ? */;
> 	if (fgets(buff, sizeof buff, stream) != NULL) ...

I think most participants in discussions of this issue don't make any
distinction between pointers and other types. The only special issue
raised by pointers is that the standard defines how to test whether a
pointer contains a value that does not actually point at anything.
isnan() does something similar for floating point types, but was new in
C99, and a conforming implementation is free to use a floating point
representation that doesn't support any NaNs.

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


#89087

FromRichard Heathfield <rjh@cpax.org.uk>
Date2016-06-14 20:25 +0100
Message-ID<njpln9$cma$1@dont-email.me>
In reply to#89084
On 14/06/16 19:59, Eric Sosman wrote:
> On 6/14/2016 11:36 AM, John Bode wrote:
>> On Sunday, June 12, 2016 at 6:21:40 PM UTC-5, G G wrote:
>>> when should a pointer to set to NULL and test whether
>>> it is NULL?
>>
>> In a non-static declaration, a pointer variable should always be
>> initialized
>> explicitly to NULL or to a valid pointer value:
>> [...]
>
>      The arguments both for and against this practice are, I think,
> too well-known to bear yet another repetition.  But here, perhaps,
> may be a slightly different slant: If universal initialization is
> good for pointers, why not for ints and doubles and struct tm's
> and every other kind of variable?

Hear, hear. :-)

I do this as a matter of course.

And yes, you're right - the arguments for and against are well-trodden.

-- 
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]


#89248

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-06-15 19:48 -0700
Message-ID<kfneg7x4zn3.fsf@x-alumni2.alumni.caltech.edu>
In reply to#89084
Eric Sosman <esosman@comcast-dot-net.invalid> writes:

> On 6/14/2016 11:36 AM, John Bode wrote:
>> On Sunday, June 12, 2016 at 6:21:40 PM UTC-5, G G wrote:
>>> when should a pointer to set to NULL and test whether
>>> it is NULL?
>>
>> In a non-static declaration, a pointer variable should always be initialized
>> explicitly to NULL or to a valid pointer value:
>> [...]
>
>     The arguments both for and against this practice are, I think,
> too well-known to bear yet another repetition.  [...]

Pretend for a moment you were talking to someone who hadn't
heard both (or perhaps either) points of view.  Can you give
a brief statement of the reasons for and against, without
advocating either side but just listing what motivations
are commonly given?

Anyone else reading this is welcome to respond with their
own pair of lists for this question.

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


#89250

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2016-06-15 23:25 -0400
Message-ID<njt68h$nh6$1@dont-email.me>
In reply to#89248
On 6/15/2016 10:48 PM, Tim Rentsch wrote:
> Eric Sosman <esosman@comcast-dot-net.invalid> writes:
>
>> On 6/14/2016 11:36 AM, John Bode wrote:
>>> On Sunday, June 12, 2016 at 6:21:40 PM UTC-5, G G wrote:
>>>> when should a pointer to set to NULL and test whether
>>>> it is NULL?
>>>
>>> In a non-static declaration, a pointer variable should always be initialized
>>> explicitly to NULL or to a valid pointer value:
>>> [...]
>>
>>     The arguments both for and against this practice are, I think,
>> too well-known to bear yet another repetition.  [...]
>
> Pretend for a moment you were talking to someone who hadn't
> heard both (or perhaps either) points of view.  Can you give
> a brief statement of the reasons for and against, without
> advocating either side but just listing what motivations
> are commonly given?

     PRO: An uninitialized pointer variable has an indeterminate value,
leading to unpredictable behavior if that variable is dereferenced.  A
pointer variable initialized to NULL has a well-determined value, but
still yields undefined behavior if dereferenced.  Nonetheless, the
undefined behavior resulting from a NULL dereference is more likely to
be reproducible than if the variable had an indeterminate value, and
"solid" bugs are easier to find and fix than "Heisenbugs."

     CON: Compilers are pretty good at warning if a variable is used
when there exists some execution path that fails to give the variable
a value prior to use.  Routinely initializing to NULL defeats any such
warnings, because no such paths exist.  It is better to learn about
"may be used uninitialized" from the compiler than (perhaps) from
testing, or from irate customers.

     COUNTER-PRO: But, but, but!!!

     COUNTER-CON: But, but, but!!!

     (For myself, I'm a CON.  Hoping for parole.)

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

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


#89300

FromJames Kuyper <jameskuyper@verizon.net>
Date2016-06-16 12:11 -0400
Message-ID<njuj48$461$1@dont-email.me>
In reply to#89250
On 06/15/2016 11:25 PM, Eric Sosman wrote:
...
>      PRO: An uninitialized pointer variable has an indeterminate value,
> leading to unpredictable behavior if that variable is dereferenced.  A
> pointer variable initialized to NULL has a well-determined value, but
> still yields undefined behavior if dereferenced.  Nonetheless, the
> undefined behavior resulting from a NULL dereference is more likely to
> be reproducible than if the variable had an indeterminate value, and
> "solid" bugs are easier to find and fix than "Heisenbugs."
> 
>      CON: Compilers are pretty good at warning if a variable is used
> when there exists some execution path that fails to give the variable
> a value prior to use.  Routinely initializing to NULL defeats any such
> warnings, because no such paths exist.  It is better to learn about
> "may be used uninitialized" from the compiler than (perhaps) from
> testing, or from irate customers.

Counter:
If an uninitialized variable is used before being initialized, in a way
that the compiler can't catch - it will cause problems.

Counter:
If it would cause problems, those problems should include making some of
your tests fail. Suitable testing is precisely what you'd have to have
done anyway, to catch the problem if you had initialized the variable
with a value not intended to be used.

Counter:
An uninitialized value that unintentionally gets used is not guaranteed
to make the tests fail. If you choose the right value to initialize it
with, you can guarantee that any such defect will cause a test to fail.

This is why I've suggested a new keyword, _NotUsed, to serve as a dummy
initializer, which does NOT disable "used when uninitialized" warnings.
However, just in case such a problem does NOT get detected, it causes
the object it initializes to be given an initial value that might depend
upon the type, which is deliberately chosen to maximize the likelihood
of creating detectable problems. If the type supports trap
representations, it will be guaranteed to be a trap; for instance, it
will be a signaling NaN if the object has a floating point type and the
implementation supports signaling NaNs.

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


#89301

Fromsupercat@casperkitty.com
Date2016-06-16 09:25 -0700
Message-ID<08235062-d1bc-42e3-a51f-ca79d825a769@googlegroups.com>
In reply to#89300
On Thursday, June 16, 2016 at 11:11:59 AM UTC-5, James Kuyper wrote:
> This is why I've suggested a new keyword, _NotUsed, to serve as a dummy
> initializer, which does NOT disable "used when uninitialized" warnings.
> However, just in case such a problem does NOT get detected, it causes
> the object it initializes to be given an initial value that might depend
> upon the type, which is deliberately chosen to maximize the likelihood
> of creating detectable problems. If the type supports trap
> representations, it will be guaranteed to be a trap; for instance, it
> will be a signaling NaN if the object has a floating point type and the
> implementation supports signaling NaNs.

I'd suggest that such things should be best implemented as intrinsic-
chained macros that accept lvalues.  If there were a standard header
file for such things, then the only thing necessary for compilers to
support such things in standard-complaint (albeit not necessarily
maximally-useful) fashion would be to define some macros in ordinary
C.  Programmers would then be able to use such macros without having to
worry about whether it might be necessary to port code to a platform
that doesn't support them yet.

In addition to setting something to a "compiler-warning-requested" value,
it would also be helpful to have a macro to set an lvalue or sequence
of lvalues in an array to any unspecified non-trap representation of that
type.  Any compiler could implement that by assigning {0}, but compilers
that don't implement certain kinds of aliasing optimizations could have
it expand to nothing, and even on those that do implement such optimizations
it would not *usually* require the compiler to generate any code, and may
in some cases allow a compiler to eliminate code (e.g. if a compiler
can determine that an object was written and then had that directive invoked
on it without an intervening read, the compiler could eliminate the write).

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


#89363

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-06-16 21:46 -0700
Message-ID<kfnziqk1kys.fsf@x-alumni2.alumni.caltech.edu>
In reply to#89300
James Kuyper <jameskuyper@verizon.net> writes:

> On 06/15/2016 11:25 PM, Eric Sosman wrote:
> ...
>>      PRO:  An uninitialized pointer variable has an indeterminate value,
>> leading to unpredictable behavior if that variable is dereferenced.  A
>> pointer variable initialized to NULL has a well-determined value, but
>> still yields undefined behavior if dereferenced.  Nonetheless, the
>> undefined behavior resulting from a NULL dereference is more likely to
>> be reproducible than if the variable had an indeterminate value, and
>> "solid" bugs are easier to find and fix than "Heisenbugs."
>>
>>      CON:  Compilers are pretty good at warning if a variable is used
>> when there exists some execution path that fails to give the variable
>> a value prior to use.  Routinely initializing to NULL defeats any such
>> warnings, because no such paths exist.  It is better to learn about
>> "may be used uninitialized" from the compiler than (perhaps) from
>> testing, or from irate customers.
>
> Counter:
> If an uninitialized variable is used before being initialized, in a way
> that the compiler can't catch - it will cause problems.  [...]

There are no such cases.  A conservative analysis can catch every
situation where a variable might be used before being given an
initial value, provided of course that we are willing to tolerate
some false positives.

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


#89366

FromGareth Owen <gwowen@gmail.com>
Date2016-06-17 06:13 +0100
Message-ID<8760t84cud.fsf@gmail.com>
In reply to#89363
Tim Rentsch <txr@alumni.caltech.edu> writes:

>> Counter:
>> If an uninitialized variable is used before being initialized, in a way
>> that the compiler can't catch - it will cause problems.  [...]
>
> There are no such cases.  

There are no cases a compiler *can't* catch.  There are cases that
compilers don't catch[0].  Most notably, if a pointer to an uninitialized
variable is passed to a function defined in a different translation
unit.

> A conservative analysis can catch every situation where a variable
> might be used before being given an initial value, provided of course
> that we are willing to tolerate some false positives.

A sufficiently good compiler .... 
Nevertheless, no existing compiler known to me does such an exhaustive search.

[0] There are also cases that a single compiler sometimes catches,
    depending on which compiler flags you use. Optimisations often catch extra things.

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


#89368

FromRobert Wessel <robertwessel2@yahoo.com>
Date2016-06-17 02:03 -0500
Message-ID<0q77mbtokkc5actoft100lut2eog9cql60@4ax.com>
In reply to#89366
On Fri, 17 Jun 2016 06:13:30 +0100, Gareth Owen <gwowen@gmail.com>
wrote:

>Tim Rentsch <txr@alumni.caltech.edu> writes:
>
>>> Counter:
>>> If an uninitialized variable is used before being initialized, in a way
>>> that the compiler can't catch - it will cause problems.  [...]
>>
>> There are no such cases.  
>
>There are no cases a compiler *can't* catch.  There are cases that
>compilers don't catch[0].  Most notably, if a pointer to an uninitialized
>variable is passed to a function defined in a different translation
>unit.


AFAIK, determining if a program will hit one of a set of statements
(I) before one of another set of statements (U), is equivalent to the
halting problem.  So in general I don't think your statement is true.

Of course there are many cases that *can* be caught, but I don't think
they can all be caught, at least not reliably (FSVO "reliably

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


#89396

FromMartin Shobe <mashobe9@gmail.com>
Date2016-06-17 07:07 -0500
Message-ID<nk0p62$tp2$1@dont-email.me>
In reply to#89368
On 6/17/2016 2:03 AM, Robert Wessel wrote:
> On Fri, 17 Jun 2016 06:13:30 +0100, Gareth Owen <gwowen@gmail.com>
> wrote:
>
>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>
>>>> Counter:
>>>> If an uninitialized variable is used before being initialized, in a way
>>>> that the compiler can't catch - it will cause problems.  [...]
>>>
>>> There are no such cases.
>>
>> There are no cases a compiler *can't* catch.  There are cases that
>> compilers don't catch[0].  Most notably, if a pointer to an uninitialized
>> variable is passed to a function defined in a different translation
>> unit.
>
>
> AFAIK, determining if a program will hit one of a set of statements
> (I) before one of another set of statements (U), is equivalent to the
> halting problem.  So in general I don't think your statement is true.
>
> Of course there are many cases that *can* be caught, but I don't think
> they can all be caught, at least not reliably (FSVO "reliably

Issuing a warning for every (and only) those variables that are used 
uninitialized is equivalent to the halting problem. However, Tim did say 
that you would have to be willing to accept some false positives.

Martin Shobe

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


Page 4 of 5 — ← Prev page 1 2 3 [4] 5  Next page →

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


csiph-web