Logical Value Of A Pointer

N

Nosophorus

Hi! :)

I was coding a trivial problem concerning static variables and
pointers intended to scan/read an array, when I took a hint in another
code. So, an excerpt of the final version of my code is:

int func1(int *a = 0)
{
static int *p;

if(a) //<--*THIS LINE*
{
p = a;
return(*p);
}
else
if(*p != -1)
{
p = p + 1;
return(*p);
}
else
return(0);
}

The function "func1" takes a pointer (named "a") to an int and the
default value of that pointer is zero. What interests me is the
meaning of the line "if(a)".

What I know is that if a parameter is passed to the function "func1",
then the "if(a)" is triggered and all the lines inside its scope are
run. BUT, I do not know what kind of result is given by that line
( the "if(a)" ). It's a logical one (TRUE, FALSE)? Does a pointer have
a logical value or something else in a situation like that?

It seems strange to me that a pointer without the dereference operator
can be used in an "if" statement. :-/

I appreciate any explanation and further help.

Thank You!

Marcelo de Brito
 
S

ssylee

Hi! :)

I was coding a trivial problem concerning static variables and
pointers intended to scan/read an array, when I took a hint in another
code. So, an excerpt of the final version of my code is:

int func1(int *a = 0)
{
  static int *p;

  if(a) //<--*THIS LINE*
 {
    p = a;
    return(*p);
 }
 else
    if(*p != -1)
    {
       p = p + 1;
       return(*p);
     }
     else
        return(0);

}

The function "func1" takes a pointer (named "a") to an int and the
default value of that pointer is zero. What interests me is the
meaning of the line "if(a)".

What I know is that if a parameter is passed to the function "func1",
then the "if(a)" is triggered and all the lines inside its scope are
run. BUT, I do not know what kind of result is given by that line
( the "if(a)" ). It's a logical one (TRUE, FALSE)? Does a pointer have
a logical value or something else in a situation like that?

It seems strange to me that a pointer without the dereference operator
can be used in an "if" statement. :-/

I appreciate any explanation and further help.

Thank You!

Marcelo de Brito

The pointer without the dereferencing is used to see if the pointer is
a dangling pointer, or rather a pointer that points to null. Basically
checks the validity of the pointer.
 
M

Marcel Müller

Nosophorus said:
int func1(int *a = 0)
{
static int *p;

if(a) //<--*THIS LINE*
The function "func1" takes a pointer (named "a") to an int and the
default value of that pointer is zero. What interests me is the
meaning of the line "if(a)".

'if (a)' is a short cut for 'if (a != 0)'. This is the same for pointers
as for any other value a.

Btw. for clearification I would recommend to write

int func1(int *a = NULL)

and consequently

return NULL;

at the bottom.


Marcel
 
J

James Kanze

I was coding a trivial problem concerning static variables and
pointers intended to scan/read an array, when I took a hint in
another code. So, an excerpt of the final version of my code
is:
int func1(int *a = 0)
{
static int *p;
if(a) //<--*THIS LINE*
{
p = a;
return(*p);
}
else
if(*p != -1)
{
p = p + 1;
return(*p);
}
else
return(0);
}
The function "func1" takes a pointer (named "a") to an int and
the default value of that pointer is zero. What interests me
is the meaning of the line "if(a)".
What I know is that if a parameter is passed to the function
"func1", then the "if(a)" is triggered and all the lines
inside its scope are run. BUT, I do not know what kind of
result is given by that line ( the "if(a)" ). It's a logical
one (TRUE, FALSE)? Does a pointer have a logical value or
something else in a situation like that?

For historical reasons, a pointer implicitly converts to bool,
with a null pointer converting to false, and all other pointer
values converting to true. In general, it's better to avoid the
implicit convertion, and write what you mean:
if ( a != NULL ) ...

There's also some discussion over whether it's better to use 0
or NULL as a null pointer constant. I prefer NULL, but my
opinion here is far from universal, and there are serious
problems with both---the next version of the standard will
introduce a nullptr which should solve the problem.

Also, most programmers would consider "else if" a single
construct, and not indent additionally for the second if. (What
happens when you have a string of else/if?)
 
N

Nosophorus

Hi, guys!

Thank you very much for the quick and clarifying replies! :)

I have not been aware of that pointer implicit setting to a logical
value.

If someone else has something to add, feel free to do it!

Thank You!

Marcelo de Brito
 
N

Nosophorus

James,

Just a simple question (and a curiosity too): Where did you gather
that information of pointer setting implicitly to a logical value?
Could you, please, point the reference?

Thank You!

Marcelo de Brito
 
M

Michael DOUBEZ

James Kanze wrote:
[snip]
For historical reasons, a pointer implicitly converts to bool,
with a null pointer converting to false, and all other pointer
values converting to true. In general, it's better to avoid the
implicit convertion, and write what you mean:
if ( a != NULL ) ...

There's also some discussion over whether it's better to use 0
or NULL as a null pointer constant. I prefer NULL, but my
opinion here is far from universal, and there are serious
problems with both---the next version of the standard will
introduce a nullptr which should solve the problem.

Will it solve the problem of false decaying to NULL pointer ?
Like in:
std::string str(false);

It throws a std::logic_error but compile nonetheless.
 
T

Triple-DES

James,

Just a simple question (and a curiosity too): Where did you gather
that information of pointer setting implicitly to a logical value?
Could you, please, point the reference?

From the C++ standard:

4.12/1:
"(...) A zero value, null pointer value, or null member pointer value
is converted to false; any other value is converted to true."
 
J

James Kanze

James Kanze wrote:
[snip]
For historical reasons, a pointer implicitly converts to bool,
with a null pointer converting to false, and all other pointer
values converting to true. In general, it's better to avoid the
implicit convertion, and write what you mean:
if ( a != NULL ) ...
There's also some discussion over whether it's better to use 0
or NULL as a null pointer constant. I prefer NULL, but my
opinion here is far from universal, and there are serious
problems with both---the next version of the standard will
introduce a nullptr which should solve the problem.
Will it solve the problem of false decaying to NULL pointer ?
Like in:
std::string str(false);

Probably not. Anything that would solve that would also break
existing code:-(. (That could have been solved when bool was
introduced, by adding words to the definition of a null pointer
constant to the effect that it could not have type bool. But I
suspect that no one happened to think of it.)
It throws a std::logic_error but compile nonetheless.

It's undefined behavior; anything can happen. In any reasonably
good implementation, it will core dump immediately.
 
J

James Kanze

First, it may be just a language problem (supposing Nosophorus
is not a native English speaker), but there is no "setting"
involved---it's an implicit conversion.
From the C++ standard:
4.12/1:
"(...) A zero value, null pointer value, or null member pointer value
is converted to false; any other value is converted to true."

And before that, from the C standard, and before that from
Kernighan and Richie. It's been that way from the earliest days
of C (which inherited it from B, no doubt, where it actually
makes sense).
 
A

Andrew Koenig

For historical reasons, a pointer implicitly converts to bool,
with a null pointer converting to false, and all other pointer
values converting to true. In general, it's better to avoid the
implicit convertion, and write what you mean:
if ( a != NULL ) ...


Why do you think it's better? I don't think so, but maybe you can convince
me.
 
A

Alf P. Steinbach

* Andrew Koenig:
Why do you think it's better? I don't think so, but maybe you can convince
me.

Don't know if this is James' reason, but relying on the implicit conversion here
one may acquire the habit of generally relying on implicit conversion to bool,
and e.g. the Visual C++ compiler produces silly-warnings (it actually thinks it
affects /performance/ :) ) in some other situations, e.g. for a 'return'. And
without a clean compile, no warnings, one doesn't know whether one has ignored
some serious warning, such as e.g. comparision between signed/unsigned.

However, since I really dislike uppercase in source code I'd write

if( a != 0 )



Cheers,

- Alf
 
J

James Kanze

"James Kanze" <[email protected]> wrote in message
Why do you think it's better? I don't think so, but maybe you
can convince me.

For the same reason implicit conversions in general are to be
avoided. A pointer isn't a bool, so it doesn't make sense to
use it as one; doing so only leads to confusion. Say what you
mean, and mean what you say.

(BTW: you're the co-author of the original proposal for bool.
And there, unless I'm remembering wrong, you proposed
deprecating the above conversion. Have you changed your mind?
And if so, what made you change it?)
 
A

Alf P. Steinbach

* Pete Becker:
And the obvious answer to that is that the compiler should not dictate
coding style. Who knows more about your application domain: the compiler
writer or you?

Turn off stupid warnings.

Sometimes, for some other warnings, that's the only practical recourse.

However, in this particular case just writing explicit code as one ideally
should anyway, makes that unnecessary, and not only for the original programmer
but for all using the code.

The code-should-be-explicit argument isn't, from my point of view, that
compelling on its own for the conversion of pointer to bool, which after all for
some is idiomatic style. But coupled with the (e.g. MSVC) silly-warnings, which
also on its own is a rather weak argument, I think it sums up to a good
argument. For AFAIK there's really no good reason to omit the comparision.


Cheers,

- Alf
 
L

Lionel B

Why do you think it's better? I don't think so, but maybe you can
convince me.

It makes the intent of the coder clearer?

If I see "if (a != NULL)" I immediately know that a is a pointer and that
we're checking that it's not a null pointer. Or more precisely, if this
is /not/ the case, then I'm dealing with such a perverse coder that all
bets are off...

If I see "if (a != 0)" then I have fewer clues what's going on and quite
likely have to check a lot of other code to find out.
 
N

Noah Roberts

Pete said:
Turn off stupid warnings.

I couldn't disagree more. There are too many easy mistakes you can make
which the compiler can warn you about long before you have to hunt them
down in debugging. Many of those mistakes can cost many hours if they
make it to that point.

One great example: forgetting to make your destructor virtual when it
should be.
 
L

Lionel B

Puhleez. Who names a pointer 'a', anyway?

Not me. I was quoting a previous poster.

Ok, maybe "immediately know" is a bit strong... "get a strong hint" might
be better.
Seriously. You're basing
the need in one *style* rule on allowing another style rule to be
violated.

You lost me there.
Not to mention the practice Microsoft uses for all its API "handles"
(like HWND, HDC, HINSTANCE, etc.) allowing comparing them to NULL. Since
they aren't necessarily pointers (and they weren't in the beginning,
BTW), the expression

if (hMyWindow != NULL)

promoted by *tons* of code originated in MS itself is simply wrong
because the goal was to compare it agains 0 (*zero*). It's only many
years later they devised a scheme where a 'HANDLE' would be compared to
'INVALID_HANDLE_VALUE' (or some such), thus breaking their own rule,
probably caused by the fact that those 'HANDLE' values with all bits
cleared were actually *valid*.

<shrug> I don't program on MS Windows... but exactly. My understanding is
that NULL (as inherited from C) is *specifically* to represent a null
pointer constant. If Microsoft choose/chose to subvert that then boo sucks
to them. I guess if I had to I'd deal with it I would, grudgingly.
The statement

if (a)

does exactly the same thing, but more. To me (and to Andrew, probably)
it says that 'a' is something that can be 'false' ("wrong", "invalid",
whatever other meaning you can hang on the value 'false'), and we're
checking that it isn't, IOW we're checking that 'a' is "fine", "OK",
"valid", "in good standing" (or whatever other meaning you can hang onto
the value 'true').

To me it says that 'a' is something that has an implicit conversion to
'bool' ... and who knows what that boolean value represents in the mind of
the programmer? Not me, as a poor mind-reader, without checking (quite
possibly inadequately documented) code.

On the other hand, 'i != 0' or 'p != NULL' or 'hMyWindow !=
INVALID_HANDLE_VALUE' or 'myObect.is_valid()' or whatever simply expresses
intent far better.
Who cares that 'a' is a pointer? FWIW it could be a
class that *acts* like a pointer. And the class can have a defined
conversion to 'bool' that isn't comparing the stored address to some
special "invalid address" pattern.

Sure, so STL iterators "act like pointers" in some ways, but heaven knows
what 'if (myitr)' might mean... as opposed to, say, 'if (myitr !=
myContainer.end()'.
The whole point of the implicit conversions is, well, duck typing.
Allowing pointers to be converted to bool provides us with the ability
to use pointers in logical expressions without having to write

.. != <somespecialexpression>

. If you don't want to use it, don't use it. But I use it, and will
continue using it because the benefits outweigh the problems it might
create for people who don't [want to] understand the language to its
fullest and need to maintain my code. Figuratively speaking, of course.

My dirty little secret is that I have been known to use it - occasionally
out of laziness, more usually to maintain consistency with someone else's
code. It just smacks of an obfuscatory C-ism to me.

I probably should have said If I see "if (a)" there.
<shrug> If that code is part of a template, it would work just fine for
*any type* that defines non-equality comparison to zero, pointers and
integrals alike. And why care what 'a' is. What's going on is the
comparison with zero, which probably has some meaning in the context.

Probably... until some coder comes along and instantiates the template
with some type for which the comparison is inappropriate. I don't think
that's so far-fetched. For instance I can envisage a signed integer-based
type for which the semantics of "valid" means > 0 (sure you say, maybe it
should not be signed then, but perhaps it needs to do signed arithmetic).
Then 'if (a)' - tucked away in some template - does *not* equate to
"valid". Ouch.
Ifthat's not a clue enough for you, then you probably don't understand
the actual context, and, yes, you would need "to check a lot of other
code to find out".

I would indeed.
 
B

Bertrand

Lionel said:
On Fri, 30 Jan 2009 10:02:29 -0500, Victor Bazarov wrote:

(Snip)
<shrug> I don't program on MS Windows... but exactly. My understanding is
that NULL (as inherited from C) is *specifically* to represent a null
pointer constant. If Microsoft choose/chose to subvert that then boo sucks
to them. I guess if I had to I'd deal with it I would, grudgingly.
I thought it has something to do with the fact that with C an invalid
pointer was not necessarily set to 0 on all platforms, hence the need
for a special value. Something that C++ decided not to carry on, and
used 0 for invalid pointers; thus legitimating the usage of implicit
conversion to bool.

btw, if example of the STL serves, several classes provide an implicit
conversion to bool to express the meaning of /valid/. streams are an
example.
Ok, admittedly, the most relevant one to the present discussion
precisely lacks it (std::auto_ptr). However, I don't think your argument
holds for it either:
if( p.get() == 0 )
does not /mean/ more than:
if( p.get() )

boost::shared_ptr also defines an implicit conversion to bool. So if
Boost does it, it does not look like a bad practice to me.

To add to the length of this thread, i will mention that I have a
personal preference for:
p ? p->something : something_else;
over:
p == 0 ? p->something : something_else;

It's pretty clear what's going on in former case, so no need to be over
redundant.

It's a bit like those who write:
if( condition == true )
or:
return condition ? true : false;
or even:
return condition == true ? true : false;


Anyway, that's probably one of those threads that will end up exactly as
it started. Nowhere! But I'm glad I will have contributed to it ;-)
 
L

Lionel B

I thought it has something to do with the fact that with C an invalid
pointer was not necessarily set to 0 on all platforms, hence the need
for a special value. Something that C++ decided not to carry on, and
used 0 for invalid pointers; thus legitimating the usage of implicit
conversion to bool.

Sure, I'm not claiming it's "wrong" to write 'if (p)', simply that 'if (p
== NULL)' - or, for that matter, 'if (p == 0)' - is clearer in its intent.
btw, if example of the STL serves, several classes provide an implicit
conversion to bool to express the meaning of /valid/. streams are an
example.
Ok, admittedly, the most relevant one to the present discussion
precisely lacks it (std::auto_ptr). However, I don't think your argument
holds for it either:

Actually my argument re. STL was about container iterators.

Sure the streams implicit conversion is useful and such a common idiom
that it seems perfectly natural in that context. I guess I'm arguing
against general usage where the context is not necessarily that clearcut.
if( p.get() == 0 )
does not /mean/ more than:
if( p.get() )

I guess you meant 'if( !p.get() )' ... now which style was clearer? ;-)

[...]
Anyway, that's probably one of those threads that will end up exactly as
it started. Nowhere! But I'm glad I will have contributed to it ;-)

For sure. I guess it's all about personal preferences. I'm really not too
exercised about it.
 
J

James Kanze

I couldn't disagree more. There are too many easy mistakes
you can make which the compiler can warn you about long before
you have to hunt them down in debugging. Many of those
mistakes can cost many hours if they make it to that point.

He didn't say turn off all warnings. He said turn off stupid
warnings. For whatever reasons, every compiler I've ever used
has some really stupid warnings, along side many very useful
ones. If you can turn them off with a compile line option,
fine; most of the time, we've ended up piping the compiler
output through sed, to get rid of some we couldn't turn off.
One great example: forgetting to make your destructor virtual
when it should be.

The problem is that the compiler generally can't know when it
should be, so it's almost impossible to get a good warning for
this. (Warning if there are virtual functions and the
destructor is public is probably close enough, however. It
shouldn't result in too many false warnings.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top