null ptr test

Code snippet showing null pointer check if (!array)return . How does the expression (!array) work to test for null ptr?

1
2
3
4
5
6
7
8
9
void printArray(int *array, int length)
{
    
    if (!array)
        return;
 
    for (int index=0; index < length; ++index)
        cout << array[index] << ' ';
}
The condition in an if statement is evaluated as a boolean. If the expression evaluates to zero, that's equivalent to false. It is non-zero, it's true. A null pointer is zero, and so evaluates to false.
I apologize for fussing over this question. I understand the outcomes of evaluation above but taking it a step back how does array evaluate to anything given that it is an array.
given that it is an array

We don't know that it is an array. The only information we have is that array is a pointer to int.
Last edited on
given that it is an array

Given that you do test for nullness, you already do assume that somebody would write:
printArray( nullptr, 7 );

That is certainly not an array. Neither is there any array in the following code:
1
2
int foo = 42;
printArray( &foo, 1 );


You can document the function and urge the user to call it with "real" arrays, but syntactically a pointer is just a pointer.
Ok,

The only information we have is that array is a pointer to int.


How does the NOT operator effect pointer to int? What is the step by step?

Start with !(ptr to integer)

Thx
Last edited on
the NOT operator just allows one to avoid having to write code like this, it gives us the 'else' condition directly:
1
2
3
4
5
6
7
8
    if (array)
    {
        // do nothing
    }
    else
    {
        return;
    }


In this case, there's no particular 'magic' involved. Though with user-defined types (classes) one could define the ! operator to do something specific, but that's another story.

We're left with the simple logic which goes,
evaluate the expression. If it is zero, interpret it as logical false. Anything non-zero is considered logical true.

ok, so array is evaluated to a (number) - if so what number is that? I think somewhere down the line I missed something about (expressions) and evaluations ().

Simply put what is if(array)
1
2
3
4
if (array)
    {
        // do nothing
    }
Last edited on
What number is that - well it is the address of the location pointed to. If the function was called with an array as the first parameter, then the number is the address of that array.
Sorry I am dragging this on.

lets say for example the number is (making it up) 00xhegy

if (00xhegy)
...

evaluate the expression


How do we evaluate (00xhegy) into true/false? I see an address.
I think it might confuse the discussion a bit that a pointer variable in the example is named "array" and it might point to an array.

The operator! is unary. It has one bool operand and it returns a bool value.

If the operand is not bool, then a conversion to bool must occur before the NOT is evaluated.

Pointer's value is an address. Address is a number. A number is either zero or non-zero. There is an implicit conversion from char/number/pointer to bool: 0 -> false, non-zero -> true.
Pointer's value is an address. Address is a number. A number is either zero or non-zero. There is an implicit conversion from char/number/pointer to bool: 0 -> false, non-zero -> true.


An address is an address. A pointer that compares equal to nullptr (and is therefore required to evaluate to false in the context of a boolean expression) may not contain the bit pattern for 0.

Some interesting discussion:
http://stackoverflow.com/questions/2759845/why-is-address-zero-used-for-the-null-pointer
Pointer's value is an address. Address is a number. A number is either zero or non-zero. There is an implicit conversion from char/number/pointer to bool: 0 -> false, non-zero -> true.

That was part of the missing piece for me.

The implicit conversion makes possible a comparison. By itself !(array) I didn't see a comparison possibility available -- looked like it was being compared to itself. It all made sense to me when the implicit conversion to bool that makes a comparison possible was brought to discussion. Now there are at least 2 decision states possible from one entity !(array).
Last edited on
As I said in my first post in this thread:

MikeyBoy wrote:
If the expression evaluates to zero, that's equivalent to false. It is non-zero, it's true. A null pointer is zero, and so evaluates to false.

I had assumed it would follow naturally that a non-null pointer is not zero, and so evaluates to true.
Last edited on
You were correct about the end result of the expression. You named the possible outcomes but it was the implicit conversion to bool that allowed the expression to be evaluated as such in the first place: zero, non-zero and null pointer.
I had assumed it would follow naturally that a non-null pointer is not zero, and so evaluates to true.


Again, we're oversimplifying. A null pointer is required to compare equal to a literal 0. It is not required to be 0. Assigning a pointer the literal 0 is required to set it to the value that indicates it is a null pointer, which may or may not be 0. See the link I posted up-thread.
Again, we're oversimplifying.

I prefer to think of it as "abstracting" ;)
> but it was the implicit conversion to bool that allowed the expression to be evaluated as such in the first place

Yes; that is the essence - the implicit conversion from pointer to bool.

Note that while any pointer can be implicitly converted to bool (either true or false), for some pointers, there is no direct conversion (either implicit or explicit) to any other integer type.
1
2
3
4
5
6
7
8
9
10
11
12
13
struct A
{
    void foo() const {}
};

int main()
{
    auto pointer = &A::foo ;
    bool not_null = pointer ; // fine: implicit converstion from pointer to bool

    int not_zero = reinterpret_cast<int>(pointer) ; // *** error: invalid cast
    not_zero = static_cast<int>(pointer) ; // *** error: invalid cast
}

http://coliru.stacked-crooked.com/a/909c2fed18b15c6d
Topic archived. No new replies allowed.