简体   繁体   中英

If in if condition string is given it is treated as true but what it return?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM