Why exactly is a string literal in an if-condition treated as true?
if("whatiamreturning")
//this is true. I want to know y?
Based on the above, what happens here?
#include<stdio.h>
void main() {
static int i;
for(;;) { //infinite loop
if(i+++"The Matrix")
// what is happening in the above line?
printf("Memento");
else
break;
}
}
It will return the address of first element of the string whatiamreturning
.
Basically when you assign a string literal to a char
pointer
char *p;
p = "whatiamreturning";
the assignment doesn't copy the the characters in whatiamreturning
, instead it makes p
point to the first character of the string and that's why string literals can be sub-scripted
char ch = "whatiamreturning"[1];
ch
will will have character h
now. This worked because compiler treated whatiamreturning
as a char *
and calculated the base address of the literal.
if(i+++"The Matrix")
is equivalent to
if( i++ + "The Matrix")
or it can be rewritten as
if(&("The Matrix"[i++]))
which will be true
for every i
and results in an infinite loop. Ultimately, the code will suffer from undefined behavior due to integer overflow for variable i
.
if(i+++"The Matrix") // what is happening here please help here to understand
This will take the value of i
, add the pointer value of the location of the string "The Matrix"
in memory and compare it to zero. After that it will increase the value of i
by one.
It's not very useful, since the pointer value could be basically any random number (it depends on architecture, OS, etc). And thus the whole program amounts to printing Memento
a random number of times (likely the same number each run though).
Perhaps you meant to write if(*(i+++"The Matrix"))
. That would loop 10 times until it i+"The Matrix"
evaluates to the address pointing to the NUL
byte at the end of the string, and *(i+"The Matrix")
will thus return 0
.
Btw, spaces are a nice way to make your code more readable.
if("whatiamreturning")
is equivalent to
if (1)
This is because "whatiamreturning"
is a char []
that decays into a non-NULL char const*
inside the if()
. Any non-NULL pointer evaluates to true
in the context of a boolean expression.
The line
if(i+++"The Matrix")
can be simplified to:
if( (i++) + "The Matrix")
In the first iteration of the loop, the value of i
is 0
. Hence, the (i++) + "The Matrix"
evaluates to "The Matrix"
.
In the second iteration of the loop, the value of i
is 1
. Hence, the (i++) + "The Matrix"
evaluates to "he Matrix"
.
However, the loop never ends and goes into the territory of undefined behavior since (i++) + "The Matrix"
never evaluates to 0
and the value of i
keeps on increasing.
Perhaps they meant to use:
if(i++["The Matrix"])
which will allow the expression inside if()
it to be 0
after 10
iterations.
Update
If you are following somebody else's code, stay away anything else that they have written. The main
function can be cleaned up to:
int main() {
char name[] = "The Matrix";
int i = 0;
for( ; name[i] != '\0'; ++i )
{
printf("Memento\n");
}
}
Why exactly is a string literal in an if-condition treated as true?
if("whatiamreturning")
The string literal "whatiamreturning"
is a constant of type char[]
.
In nearly all contexts, including this one, arrays decay to pointers to their first element.
In a boolean context, like the condition of an if
-statement, all non-zero values are true.
As the pointer points to an object, it is not the null-pointer, and thus is true.
Based on the above, what happens here?
#include<stdio.h> void main() {
The above is your first instance of Undefined Behavior , whatever happens, it is right.
We will now pretend the error is corrected by substituting int
for void
.
Now, your loop:
static int i;
Static variables are default initialized, so i
starts with value 0.
for(;;) { //infinite loop
if(i+++"The Matrix")
// what is happening in the above line?
printf("Memento");
else
break;
}
This loop has Undefined Behavior as well.
The condition takes i
and adds it to the string literal "Memento"
which decayed to a pointer like in the previous example, interpreting the resultant pointer in a boolean context, and as a side-effect incrementing i
.
As long as i
is no more than strlen("The Matrix")+1
on entry, everything is ok, the pointer points to an element of the string literal or one past, and the standard guarantees that's not a null pointer.
The moment it is though, all hell breaks loose because calculating such a pointer is Undefined Behavior .
Well, now that we know the loop is UB, let's ignore the loop too. The rest of the program is:
}
Which is ok, because even though main
has a return type of int
, there's a special rule which states that if control reaches the end of main
without executing a return
-statement, an implicit return 0;
is added.
Side-note: If an execution of a program encounters Undefined Behavior anywhere, the whole program is undefined, not only from that point on: Undefined behavior can result in time travel (among other things, but time travel is the funkiest)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.