Comparing char * with string literal

Discussion in 'C Programming' started by subramanian100in@yahoo.com, India, Mar 8, 2007.

  1. , India

    , India Guest

    Suppose we have

    char *a = "test message" ;

    Consider the comparison

    if (a == "string")
    .....

    Here "string" is an array of characters. So shouldn't the compiler
    generate an error/warning for this comparison ?
    , India, Mar 8, 2007
    #1
    1. Advertising

  2. , India

    bytebro Guest

    On 8 Mar, 08:29, ", India"
    <> wrote:
    > Suppose we have
    >
    > char *a = "test message" ;
    >
    > Consider the comparison
    >
    > if (a == "string")
    > .....
    >
    > Here "string" is an array of characters. So shouldn't the compiler
    > generate an error/warning for this comparison ?


    Why? It is pretty much equivalent to

    if (address1 == address2)...

    which is fairly obviously OK.
    bytebro, Mar 8, 2007
    #2
    1. Advertising

  3. , India

    Chris Dollin Guest

    , India wrote:

    > Suppose we have
    >
    > char *a = "test message" ;
    >
    > Consider the comparison
    >
    > if (a == "string")
    > .....
    >
    > Here "string" is an array of characters. So shouldn't the compiler
    > generate an error/warning for this comparison ?


    It's not required to generate a disgnostic. A good warning
    for this wouldn't look like the one you're thinking of.

    In the expression `a == "string"`, the literal is evaulated
    in what I shall call "value" context, as opposed to "target of
    assignment" context [1] or "operand of sizeof" context.
    Remember that a string literal denotes an array, and that an
    array in value context decays into a pointer to its first
    element.

    So we're comparing `a`, which is a pointer-to-char, to the
    address of the `s` in `"string"`, which is pointer-to-char.
    No problem, no diagnostic. Happy times!

    But [2] ... this is a pretty useless comparision, and not just
    because we know that `a` points to a different string; it's
    worse than that, Jim.

    The only way for the comparision to be true is if `a` points
    to that very same `s`. Can it? At first glance no, because
    there's no other variable referring to that `s`, and no
    other path to get to that literal. So perhaps the compiler
    should warn "comparision can never succeed"? Again no: suppose
    we had

    char *a = strchr( "long string", 's' );

    so that it points to the `s` in "long string". The compiler
    is /permitted/ to have the literal "string" share store with
    the tail of "long string".

    So the warning might be something like

    "that comparision doesn't have a stable result, because
    it depends whether whatever `a` points to is part of
    some string literal somewhere in this program that ends
    with `string`. I suggest you don't do that. Maybe you
    should be using `strcmp`?"

    And you have to rush out and buy a bigger monitor.

    [1] Which I'd call "lvalue" context except I'd risk confusion
    and a flame war.

    [2] You knew I was going to say that.

    --
    Chris "electric hedgehog" Dollin
    The shortcuts are all full of people using them.
    Chris Dollin, Mar 8, 2007
    #3
  4. , India

    Sheth Raxit Guest

    On Mar 8, 1:29 pm, ", India"
    <> wrote:
    > Suppose we have
    >
    > char *a = "test message" ;
    >
    > Consider the comparison
    >
    > if (a == "string")
    > .....
    >
    > Here "string" is an array of characters. So shouldn't the compiler
    > generate an error/warning for this comparison ?


    why ?
    strings is an array of characters (terminating with \0 ),
    arrays are having base address,string's base address points to its
    first char

    you are comparing char * to char * (assume we are not talking about
    const)


    --Raxit
    Sheth Raxit, Mar 8, 2007
    #4
  5. , India said:

    > Suppose we have
    >
    > char *a = "test message" ;


    Better: const char *a = "test message";

    >
    > Consider the comparison
    >
    > if (a == "string")
    > .....
    >
    > Here "string" is an array of characters.


    Yes, it is. But it is being used in a value context, and so the address
    of its first element is used instead. That address is compared to the
    address stored in a. If those addresses are the same, then == will
    yield 1 as its result. If the addresses are different (regardless of
    the similarity or otherwise of the objects pointed to), then == will
    yield 0 as its result.

    > So shouldn't the compiler
    > generate an error/warning for this comparison ?


    No.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
    Richard Heathfield, Mar 8, 2007
    #5
  6. , India

    Eric Sosman Guest

    , India wrote:
    > Suppose we have
    >
    > char *a = "test message" ;
    >
    > Consider the comparison
    >
    > if (a == "string")
    > .....
    >
    > Here "string" is an array of characters. So shouldn't the compiler
    > generate an error/warning for this comparison ?


    No, because the comparison is perfectly legal. One
    can even imagine a scenario where it would "work," such as:

    #define YES "Da"
    #define NO "Nyet"
    const char *decision = NO;
    if (this && that && moonPhase() == MOON_FULL)
    decision = YES;
    doSomething();
    if (decision == YES) /* here it is ... */
    doMore();

    Personally, I would not use strings this way; it's really
    using the pointers and not the strings themselves. But
    it *is* a legal usage, and the compiler must not reject
    the program because of it.

    --
    Eric Sosman
    lid
    Eric Sosman, Mar 8, 2007
    #6
  7. , India

    Chris Dollin Guest

    Eric Sosman wrote:

    > No, because the comparison is perfectly legal. One
    > can even imagine a scenario where it would "work," such as:
    >
    > #define YES "Da"
    > #define NO "Nyet"
    > const char *decision = NO;
    > if (this && that && moonPhase() == MOON_FULL)
    > decision = YES;
    > doSomething();
    > if (decision == YES) /* here it is ... */
    > doMore();


    A compiler that allocated fresh store for each new string
    literal (that's allowed, right?) would be such that
    `decision == YES` would never be true.

    --
    Chris "electric hedgehog" Dollin
    Scoring, bah. If I want scoring I'll go play /Age of Steam/.
    Chris Dollin, Mar 8, 2007
    #7
  8. , India

    Eric Sosman Guest

    Chris Dollin wrote On 03/08/07 08:43,:
    > Eric Sosman wrote:
    >
    >
    >> No, because the comparison is perfectly legal. One
    >>can even imagine a scenario where it would "work," such as:
    >>
    >> #define YES "Da"
    >> #define NO "Nyet"
    >> const char *decision = NO;
    >> if (this && that && moonPhase() == MOON_FULL)
    >> decision = YES;
    >> doSomething();
    >> if (decision == YES) /* here it is ... */
    >> doMore();

    >
    >
    > A compiler that allocated fresh store for each new string
    > literal (that's allowed, right?) would be such that
    > `decision == YES` would never be true.


    <fx: self-administered dope slap> Yes, of course. It's
    been so long since I used a compiler that *didn't* combine
    identical literals (and sometimes "suffix literals," too)
    that I clean forgot about it.

    The code snippet remains legal, but is even stupider
    than I thought when I wrote it. (It begins to challenge
    my own personal stupidity level ...)

    --
    Eric Sosman, Mar 8, 2007
    #8
  9. , India

    Mike Wahler Guest

    <> wrote in message
    news:...
    > Suppose we have
    >
    > char *a = "test message" ;
    >
    > Consider the comparison
    >
    > if (a == "string")
    > .....
    >
    > Here "string" is an array of characters.


    Here, evaluation of the expression "string" evaluates
    to the address of the character 's'; this value has type
    'char *'.

    The type of 'a' is also type 'char *'.

    > So shouldn't the compiler
    > generate an error/warning for this comparison ?


    No. You're comparing two objects of the same type.

    -Mike
    Mike Wahler, Mar 8, 2007
    #9
  10. <> wrote in message
    > Suppose we have
    >
    > char *a = "test message" ;
    >
    > Consider the comparison
    >
    > if (a == "string")
    > .....
    >
    > Here "string" is an array of characters. So shouldn't the compiler
    > generate an error/warning for this comparison ?
    >

    The language doesn't always do what a programmer familiar with other
    languages would expect.
    Here the comparison is so unlikely to be a genuine piece of useful code that
    a warning is justified, however the compiler writer needs to remember and
    put in a special patch just for this situation. Justifiable for a big
    compiler, but not for a cheapo one.

    There is a similar issue with if( x = 1)
    The problem is that constructs like

    while( ch = *ptr++ )

    are idiomatic and arguably a good thing because they reduce the line count.
    Malcolm McLean, Mar 8, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. -D
    Replies:
    3
    Views:
    2,701
    Thomas Schodt
    Sep 4, 2004
  2. Zach
    Replies:
    3
    Views:
    5,522
    Mike Wahler
    Dec 12, 2004
  3. william
    Replies:
    18
    Views:
    533
    CBFalconer
    Mar 19, 2007
  4. william
    Replies:
    10
    Views:
    753
    Gavin Deane
    Mar 19, 2007
  5. Anonieko Ramos

    What's wrong with rpc-literal? Why use doc-literal?

    Anonieko Ramos, Sep 27, 2004, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    362
    Anonieko Ramos
    Sep 27, 2004
Loading...

Share This Page