Bahramdun Adil
Bahramdun Adil

Reputation: 6079

In this C code how can the expression acts as the boolean

Basically I have two questions in the code bellow:

const char *x = "abc";
const char *y = "def";

char *res = (char*)malloc(0);
char *z = res;
while (*z++ = *x++);
z--; // remove \0
while (*z++ = *y++);

printf("%s\n", res); // output: abcdef
free(res);

The purpose of this code is to add two strings in one. But how this line while (*z++ = *x++); can act as boolean 1/0, And why I even set the malloc(0); to zero it also works well without any problem??

Upvotes: 5

Views: 171

Answers (5)

user2371524
user2371524

Reputation:

But how this line while (*z++ = *x++); can act as boolean 1/0

This is because in C, an assignment is an expression and it evaluates to the value that is assigned. When *x reaches the final '\0' terminator, it evaluates to 0, therefore false in a boolean context.

This is btw a nice source of bugs due to mistyping:

if (x = 1) // always true, as a side effect assigns 1 to x

And why I even set the malloc(0); to zero it also works well without any problem??

Using the return value of malloc(0) to write values is just undefined and "works by accident". You request zero bytes, so you are never allowed to write to this allocation and malloc() could even return you a null pointer.

Citing myself here about undefined behavior:

Undefined behavior in C

C is a very low-level language and one consequence of that is the following:

Nothing will ever stop you from doing something completely wrong.

Many languages, especially those for some managed environment like Java or C# actually stop you when you do things that are not allowed, say, access an array element that does not exist. C doesn't. As long as your program is syntactically correct, the compiler won't complain. If you do something forbidden in your program, C just calls the behavior of your program undefined. This formally allows anything to happen when running the program. Often, the result will be a crash or just output of "garbage" values, as seen above. But if you're really unlucky, your program will seem to work just fine until it gets some slightly different input, and by that time, you will have a really hard time to spot where exactly your program is undefined. Therefore avoid undefined behavior by all means!.

On a side note, undefined behavior can also cause security holes. This has happened a lot in practice.

Upvotes: 6

Galik
Galik

Reputation: 48625

An assignment has a value, which is its left-hand side so:

a = b; // value of the expression is a, after the assignment

So if(a = b){} is like saying a = b; if(a){}.

In C any non zero numeric value or pointer equals true and only zero 0 or a null pointer is false.

So the expression if(*x){} is true if the char pointed to by x is any character except the null terminator character '\0'.

Putting it all together:

if(*x++ = *y++){}

Take the char pointed to by y and copy it to the char pointed to by x. Then increment both x and y. Execute the while body if that char was not the null terminator '\0'.

Sort of equivalent to:

*x = *y
exp = *x;
x++;
y++;
if(exp){}

Upvotes: 1

Hatted Rooster
Hatted Rooster

Reputation: 36483

To answer :

But how this line while (*z++ = *x++); can act as boolean 1/0

This while loop will run until *z points to NUL, since the string literal contains "abc\0" this will loop over a, b, c then it will encounter \0 which converts to 0 which will not satisfy the while and thus it terminates.

Big big disclaimer though: This code is dereferencing a pointer that was obtained by malloc(0), that is already very much undefined behaviour and thus there's no point in reasoning why this code works or doesn't work.

Upvotes: 2

Malcolm McLean
Malcolm McLean

Reputation: 6404

In C, any expression can be used as a boolean. 0 (or null for pointers) means "false", non-zero means "true".

This even includes assignments. The expression is assigned, then evaluated. So you can have code like

while(*dest++ = *src++);

This is the sort of thing that tends to give C a bad name, but it is allowed.

Upvotes: 3

Codor
Codor

Reputation: 17605

The condition

while (*z++ = *x++)

might be puzzling because of the expression concept of C which differs from some other languages. Note that strictly speaking, C does not have a boolean type. Furthermore, an assignment expression itself has a value, namely the assigned value.

Upvotes: 0

Related Questions