Is the expression 1 ? "123" : "1234" a valid one ?

Discussion in 'C Programming' started by é‚“å°§, Apr 24, 2012.

  1. Hi, everyone

    Is the following expression a valid one ?
    1 ? "123" : "1234"

    I'm not sure about the answer, but many C compilers (MSVC/GCC/Clang) support this expression.

    Firstly, string literals are of type character array. According to C specification draft n1124 section 6.5.15, conditional operator has to satisfy thefollowing constraints:

    > The first operand shall have scalar type.
    > One of the following shall hold for the second and third operands:
    > — both operands have arithmetic type;
    > — both operands have the same structure or union type;
    > — both operands have void type;
    > — both operands are pointers to qualified or unqualified versions of compatible types;


    I'm not sure where this condition is held for the expression. If for some reason the two string literals are converted to two pointers, the expressionis a valid one, otherwise it's invalid.

    > — one operand is a pointer and the other is a null pointer constant; or
    > — one operand is a pointer to an object or incomplete type and the other is a pointer to a qualified or unqualified version of void.


    Any ideas ?

    Thanks
    Yao
     
    é‚“å°§, Apr 24, 2012
    #1
    1. Advertising

  2. é‚“å°§ <> writes:

    > Hi, everyone
    >
    > Is the following expression a valid one ?
    > 1 ? "123" : "1234"


    Yes it is.

    <snip>
    > Firstly, string literals are of type character array. According to C
    > specification draft n1124 section 6.5.15, conditional operator has to
    > satisfy the following constraints:
    >
    >> The first operand shall have scalar type.
    >> One of the following shall hold for the second and third operands:
    >> — both operands have arithmetic type;
    >> — both operands have the same structure or union type;
    >> — both operands have void type;
    >> — both operands are pointers to qualified or unqualified versions of
    >> compatible types;
    >> — one operand is a pointer and the other is a null pointer constant; or
    >> — one operand is a pointer to an object or incomplete type and the
    >> other is a pointer to a qualified or unqualified version of void.


    > I'm not sure where this condition is held for the expression. If for
    > some reason the two string literals are converted to two pointers, the
    > expression is a valid one, otherwise it's invalid.


    The "for some reason" is 6.3.2.1 paragraph 3:

    "Except when it is the operand of the sizeof operator or the unary &
    operator, or is a string literal used to initialize an array, an
    expression that has type 'array of type' is converted to an
    expression with type 'pointer to type' that points to the initial
    element of the array object[...]"

    --
    Ben.
     
    Ben Bacarisse, Apr 24, 2012
    #2
    1. Advertising

  3. é‚“å°§

    Eric Sosman Guest

    On 4/24/2012 7:20 AM, é‚“å°§ wrote:
    > Hi, everyone
    >
    > Is the following expression a valid one ?
    > 1 ? "123" : "1234"


    Yes.

    > I'm not sure about the answer, but many C compilers (MSVC/GCC/Clang) support this expression.
    >
    > Firstly, string literals are of type character array. According to C specification draft n1124 section 6.5.15, conditional operator has to satisfy the following constraints:
    >
    >> The first operand shall have scalar type.


    It does.

    >> One of the following shall hold for the second and third operands:
    >> — both operands have arithmetic type;
    >> — both operands have the same structure or union type;
    >> — both operands have void type;
    >> — both operands are pointers to qualified or unqualified versions of compatible types;


    They are. When an array reference appears in an expression, it
    almost always means "pointer to the array's [0] element" (there are
    two exceptions that do not apply here). "123" generates a nameless
    array of char, and mentioning it produces a char* pointer value that
    aims at the '1'. Similarly, "1234" generates a nameless array and
    produces a char* pointer to its '1'. With this in mind, your
    expression can be analyzed as

    1 ? "123" : "1234"
    | | |
    | | |
    V V V
    (int) ? (char[4]) : {char[5])
    | | |
    | | |
    V V V
    (int) ? (char*) : (char*)

    .... and the last two operands are indeed "pointers ... of compatible
    types."

    (For the record, the two exceptions to "array references produce
    pointers in expressions" rule are: When the array is the operand of
    `sizeof', and when it is the operand of the address-of operator `&'.)

    --
    Eric Sosman
    d
     
    Eric Sosman, Apr 24, 2012
    #3
  4. é‚“å°§

    James Kuyper Guest

    On 04/24/2012 07:20 AM, é‚“å°§ wrote:
    ....
    > ... According to C specification draft n1124 section 6.5.15, ...


    Other people have already answered your question, so I'll just address a
    side issue. The current version of the C2011 standard is not greatly
    different from draft n1570; C99 is most accurately represented by draft
    n1256 (oddly enough, it's actually more complete and up-to-date than any
    official version of C99). I don't think there's any reason to rely upon
    n1124.
    --
    James Kuyper
     
    James Kuyper, Apr 24, 2012
    #4
  5. On Tuesday, April 24, 2012 7:55:14 PM UTC+8, James Kuyper wrote:
    > On 04/24/2012 07:20 AM, é‚“å°§ wrote:
    > ...
    > > ... According to C specification draft n1124 section 6.5.15, ...

    >
    > Other people have already answered your question, so I'll just address a
    > side issue. The current version of the C2011 standard is not greatly
    > different from draft n1570; C99 is most accurately represented by draft
    > n1256 (oddly enough, it's actually more complete and up-to-date than any
    > official version of C99). I don't think there's any reason to rely upon
    > n1124.
    > --
    > James Kuyper


    Thanks for the information. I picked up n1124, because google "c99 specification" showed it as the first result, I should have been more careful :-(

    Thanks for all the replies
    Yao
     
    é‚“å°§, Apr 24, 2012
    #5
  6. Eric Sosman <> writes:
    [...]
    > (For the record, the two exceptions to "array references produce
    > pointers in expressions" rule are: When the array is the operand of
    > `sizeof', and when it is the operand of the address-of operator `&'.)


    And the third is when it's a string literal in an initializer used to
    initialize an array object. Example: In

    char s[6] = "hello";

    the literal "hello" doesn't decay to a pointer; the array value is
    copied into s.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Apr 25, 2012
    #6
  7. é‚“å°§

    Eric Sosman Guest

    On 4/24/2012 9:38 PM, Keith Thompson wrote:
    > Eric Sosman<> writes:
    > [...]
    >> (For the record, the two exceptions to "array references produce
    >> pointers in expressions" rule are: When the array is the operand of
    >> `sizeof', and when it is the operand of the address-of operator `&'.)

    >
    > And the third is when it's a string literal in an initializer used to
    > initialize an array object. Example: In
    >
    > char s[6] = "hello";
    >
    > the literal "hello" doesn't decay to a pointer; the array value is
    > copied into s.


    I had intended "in expressions" to rule out initializers and
    splices of adjacent literals, but "in expressions" isn't quite
    good enough: Many initializers are expressions, and (I think) all
    initializers contain expressions. Thanks for the correction.

    Perhaps I should have said something like "array references as
    operands produce pointers, with two exceptions." (Keith knows this,
    but in case others don't: The `=' in his example is not an assignment
    operator, but a separator required by the syntax of initialization.)

    --
    Eric Sosman
    d
     
    Eric Sosman, Apr 25, 2012
    #7
    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. Sunil Menon
    Replies:
    2
    Views:
    552
    Sunil Menon
    Jul 27, 2003
  2. Eddy Soeparmin

    Phone Format (770) 123-1234

    Eddy Soeparmin, Jul 28, 2003, in forum: ASP .Net
    Replies:
    3
    Views:
    3,197
    Swanand Mokashi
    Jul 28, 2003
  3. pembed2003

    Regex to format 1234 to 1,234

    pembed2003, Apr 27, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    142
    Lukas Mai
    Apr 28, 2004
  4. Quarco

    ereg: ? 1234.56 ==> ? 1.234,56

    Quarco, Feb 9, 2005, in forum: Javascript
    Replies:
    3
    Views:
    160
    Quarco
    Feb 10, 2005
  5. David Mark
    Replies:
    58
    Views:
    1,444
    David Mark
    Dec 6, 2011
Loading...

Share This Page