Is while(*pointer) legal in C?

Viewed 102

I recently came across a lot of code snippets that use:

while (*pointer) { 
    ... ++pointer; 
}

I checked it with my lecturer whether it is good and "legal" to perform such an action, Because I thought the condition would not stop in case of pointer to integers array.

I could not get a clear answer, I would appreciate any answer if it is correct to use this case and why the condition works because it is not certain that at the end of the array will be 0 / NULL that will stop the condition.

Thanks in advance.

5 Answers

Good and legal, yes. This is used a lot.

An example, and you want to use a pointer instead of an index (that has some advantages sometimes).

Counting the number of * in a string

int counstar(char *s) {
    int n = 0;
    while(*s) if(*s++ == '*') n++;
    return n;
}

Usually, (convention) C strings are ending with a '\0', thus you know where it ends, and me mere if (*s) suffices.

For integers (and anything but strings), unless it's been specified (eg last number is 0), you don't know the size of the array, and need a variable to tell the size. However, if you know that the last one is zero, for instance, the algo would be similar to the string one above.

Adding x to n integers

void addx(int *a, int x, int n) {
   while (n--) *a++ += x;
}

If you know the last item is always 0 (and is not incremented)

void addx(int *a, int x) {
   while (*a) *a++ += x;
}

"Is while(*pointer) legal in C?"

If pointer is ensured to point to a string literal, an array of char containing a string or to an array of basic or pointer type with at least one element containing a 0 value, then yes it is correct and legal.

But else (if the array pointed to doesn´t contain at least one element with 0 value), it is not legal as you would access elements beyond the bounds of the array with that condition due to the incrementation of pointer. To dereference a pointer, pointing past the end of the array, invokes undefined behavior:

"If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated."

Source: ISO/IEC 9899:2011 (C11), 6.5.6/8

I dont know what a concret type your pointer points to, but execpt 0 or NULL, '\0' is zero too. So for C-type strings, it also can work.

A frequent use case is when there is a variable length array of pointers (for example a dynamically allocated array of strings) when its size is determined by the sentinel value equal to NULL.

Here is a very simple example

#include <stdio.h>

int main( int argc, char * argv[] )
{
    while ( *argv ) puts( *argv++ );

    return 0;
}

This works because according to the C Standard (5.1.2.2.1 Program startup)

2 If they are declared, the parameters to the main function shall obey the following constraints: ...

— argv[argc] shall be a null pointer ,,,

Yes, you can go for it. Please note that *pointer is the value at the memory location the pointer points to(or hold the address of).

Related