c++pointersstring-literalsrelational-operators

How const char* strings are compared?


Firstly, consider this example:

#include <iostream>
using namespace std;

int main()
{
    cout << ("123" == "123");
}

What do I expect: since "123" is a const char*, I expect ADDRESSES (like one of these answers said) of these strings to be compared.

... because != and == will only compare the base addresses of those strings. Not the contents of the strings themselves.

But still the output is 1. Okay, we actually don't know how to compare addresses of two prvalue objects (or at least I don't understand how it would be done). So let's declare these strings as variables and see what will happen:

#include <iostream>
using namespace std;

int main()
{
    const char* a = "1230";
    const char* b = "1230";
    cout << (a == b);
}

Still the output is 1. So const char* strings does not decay? Or compiler managed to do some optimizations and allocate memory only for one string? Ok, let's try to avoid them:

#include <iostream>
using namespace std;

int main()
{
    const char* a = "1230";
    const char* b = "1231";
    b = "1230";
    cout << (a == b);
}

Still the result is the same. Which made me think that const char* really does not decays. But that didn't made my life simpler. How then const char*s are compared?

Why here the output is 1:

#include <iostream>
using namespace std;

int main()
{
    const char* a = "1230";
    const char* b = "1231";
    cout << (a > b);
}

a is less than b, in terms of lexographical comparison, but here a is bigger. How then comparison of const char*s is implemented?


Solution

  • Yes, the linked answer is correct. operator== for pointers just compares the addresses, never their content.

    Furthermore, the compiler is free, but not required, to de-duplicate string literals, so all occurrences of a string literal are the same object, with the same address. That is what you observe and re-assignment b = "1230"; won't stop that.

    [lex.string.14] Evaluating a string-literal results in a string literal object with static storage duration, initialized from the given characters as specified above. Whether all string-literals are distinct (that is, are stored in nonoverlapping objects) and whether successive evaluations of a string-literal yield the same or a different object is unspecified.

    What should const char* decay to? Arrays decay, pointers don't.

    #include <iostream>
    using namespace std;
    
    int main()
    {
        const char* a = "1230";
        const char* b = "1231";
        cout << (a > b);
    }
    

    returns 1 just because a happens to point to a higher address than b, there is no lexiographical comparison done. Just use std::string or std::string_view if you require that.