5

Possible Duplicate:
How are string literals compiled in C?

I wrote the small code below. In this code, I think the address of first and second "hello" string would be compared. I am confused in this. In first look, I thought that both the strings would be stored in Read only memory and thus would have different address. But "equal" got printed after the execution.

When I saw the objdump, I was not not able to see the string hello. I understand that I have not taken a variable to store them, but where would "hello" be stored.

Will it be stored on STACK ?? or Will it be stored on Code Segment ??

#include<stdio.h>
int main()
{
    if ("hello" == "hello")
        printf("\n equal ");
    else
        printf("\n not equal");
    return 0;
}

When I changed the if condition to if ("hello" == "hell1"), "not equal" got printed. Again, where and how are the strings getting stored. Will it be stored on STACK ?? or Will it be stored on Code Segment ??

I would really appreciate if someone here gives me en elaborate answer. Thanks

Community
  • 1
  • 1
Manik Sidana
  • 2,005
  • 2
  • 18
  • 29
  • If you see the disassembly of this, you will notice that there is no `if` equivalent at all! Optimised out! – Pavan Manjunath May 11 '12 at 07:29
  • possible duplicate of [A basic question: How are string literals compiled in C?](http://stackoverflow.com/q/6680819/), [Why is “a” != “a” in C?](http://stackoverflow.com/q/4843640/), [C String literals: Where do they go?](http://stackoverflow.com/q/2589949/) – outis May 11 '12 at 07:29

3 Answers3

3

In your particular example, the "hello" strings are not even part of the code. The compiler is smart enough to detect that the code will always and forever anon print "equal" so it stripped them out entirely.

If your code looked like this, however:

#include<stdio.h>
int main()
{
    const char *h1 = "hello";
    const char *h2 = "hello";
    if (h1 == h2)
        printf("\n equal ");
    else
        printf("\n not equal");
    return 0;
}

You would still get "equal", even though, however, the comparison will actually be done (when compiled without extra optimizations). It's an optimization - the compiler detected that you have two identical, hard-coded strings and merged them in the resulting binary.

Whereas, if your code looked like this, the compiler wouldn't be able to guess (by default) that they're the same, and you'll see the "not equal" message:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
    char *h1 = malloc(sizeof(char) * 10);
    char *h2 = malloc(sizeof(char) * 10);

    strcpy(h1, "hello");
    strcpy(h2, "hello");

    if (h1 == h2)
        printf("\n equal ");
    else
        printf("\n not equal");

    free(h1);
    free(h2);

    return 0;
}
Mahmoud Al-Qudsi
  • 28,357
  • 12
  • 85
  • 125
  • Even without optimization, a kind of optimization has taken place in the code you show. Both `h1` and `h2` point to same locn. I think we cannot prevent the compiler from basic optimizations even at `O0`? Not sure though – Pavan Manjunath May 11 '12 at 07:39
  • @PavanManjunath I restructured my post to make it clearer. – Mahmoud Al-Qudsi May 11 '12 at 07:43
  • Since this is an address comparison, how can compiler optimize the code on the assumption of string comparison? – Manik Sidana May 11 '12 at 08:19
  • The C spec allows a compiler to produce code that behaves *as if* it were compiled compliant to the spec. For the code above, all what matters is that it produces the right output, even if for all the wrong reasons (I'm exaggerating, but that's the general idea). There's nothing in the spec to indicate that the code in my first example should print "not equal", the compiler simply takes that to the next level. – Mahmoud Al-Qudsi May 11 '12 at 08:27
  • In other words - why shouldn't it? You *assume* the two variables have different addresses, but there's no real reason that *needs* to be the case. – Mahmoud Al-Qudsi May 11 '12 at 08:36
  • How can you say that "equal" is the right output? What if a novice user thinks that == can be used for string comparison and tries the above example. – Manik Sidana May 11 '12 at 08:59
  • I am not sure, but I think you not focusing on the question the user is asking. His intent is to know what happens to "hello"=="hello" and where does compiler store the "hello"s. I am not aware of the answer though. But, consider that all optimization has been switched off, where is the allocation done and how is 'equal' getting printed. – Shrey May 11 '12 at 12:01
1

if two string compared if equal, like "hello" == "hello", there is no comparison in main at all as Pavan Manjunath said. assembly as follows:

    .file   "hello.c"
    .section    .rodata
.LC0:
    .string "\n equal "
    .text
.globl main
    .type   main, @function

but if these two string is not equal, like "hello2" == "hello", then compiler will allocate memory in .rodata for them, seems from accembly, as follows:

    .file   "hello.c"
    .section    .rodata
.LC0:
    .string "hello2"
.LC1:
    .string "hello"
vincent
  • 138
  • 4
0

String literals, as your two "hello" can be realized in read-only memory by the compiler and in addition he has the right to just realize one such literal if there value coincides.

So the outcome of your comparison is implementation defined and may even vary for different versions of the same compiler or different optimization options that you give.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • Actually, in his example, "hello" isn't stored in `.TEXT` at all. But you're correct for the modified code in my post. – Mahmoud Al-Qudsi May 11 '12 at 08:24
  • @MahmoudAl-Qudsi, for your compiler this may be the case or not. This is an implementation detail of the platform, different compilers will do differently. – Jens Gustedt May 11 '12 at 08:58