+1 an invalid constant expression

Discussion in 'C Programming' started by Francois Grieu, Jan 1, 2010.

  1. Hi,

    the embedded C compiler that I (have to) use won't compile
    enum { f = +1 };
    giving an error message on the tune of "invalid constant
    expression", although it is fine with either of
    enum { f = 1 };
    enum { f = -1 };

    It similarly refuses
    int g[ +1 ];
    but accepts (including in a global context)
    int h = +1;

    Has there EVER been a C definition where unary + is not
    allowed in constant expressions ?
    Or a common parser with this odd characteristic ?

    TIA,

    François Grieu
    Francois Grieu, Jan 1, 2010
    #1
    1. Advertising

  2. Francois Grieu

    Eric Sosman Guest

    On 1/1/2010 10:01 AM, Francois Grieu wrote:
    > Hi,
    >
    > the embedded C compiler that I (have to) use won't compile
    > enum { f = +1 };
    > giving an error message on the tune of "invalid constant
    > expression", although it is fine with either of
    > enum { f = 1 };
    > enum { f = -1 };
    >
    > It similarly refuses
    > int g[ +1 ];
    > but accepts (including in a global context)
    > int h = +1;
    >
    > Has there EVER been a C definition where unary + is not
    > allowed in constant expressions ?


    Original K&R C had no unary + operator at all; it was added
    in the 1989 ANSI Standard. It seems your compiler is in a sort
    of half-way position: It obviously recognizes unary + in some
    contexts, but not in others.

    > Or a common parser with this odd characteristic ?


    Looks like you've found one ...

    --
    Eric Sosman
    lid
    Eric Sosman, Jan 1, 2010
    #2
    1. Advertising

  3. Francois Grieu

    Kaz Kylheku Guest

    On 2010-01-01, Francois Grieu <> wrote:
    > Hi,
    >
    > the embedded C compiler that I (have to) use won't compile
    > enum { f = +1 };
    > giving an error message on the tune of "invalid constant
    > expression", although it is fine with either of
    > enum { f = 1 };
    > enum { f = -1 };
    >
    > It similarly refuses
    > int g[ +1 ];
    > but accepts (including in a global context)
    > int h = +1;
    >
    > Has there EVER been a C definition where unary + is not
    > allowed in constant expressions ?
    > Or a common parser with this odd characteristic ?


    Strictly speaking, this is a semantic issue, not a parsing issue.
    (It's not even being reported as a syntax error, right?)

    The most likely explanation is that the compiler's logic for classifying
    an expression (which parsed correctly) as a constant expression does not
    account for the unary plus operator.

    Whether or not an expression is constant in C depends on which operators
    it uses, not only a matter of what kinds of operands. For instance
    1 ? 2 : 3 is not a constant expression, because it uses the ternary operator,
    even though all of the subexpressions are constants.

    It's easy to see how this could slip through the cracks, since the unary
    plus exists only for the sake of completeness.

    You can use it to reduce an lvalue (of numeric type) to a non-lvalue:

    (+A)

    But (A + 0) will work for all arithmetic types (i.e. including pointers).

    You should report the issue to your compile vendor, but it's hardly
    a show stopper with no workaround. Why are you using unary plus at all?
    Kaz Kylheku, Jan 1, 2010
    #3
  4. Francois Grieu

    Kaz Kylheku Guest

    On 2010-01-01, Eric Sosman <> wrote:
    > On 1/1/2010 10:01 AM, Francois Grieu wrote:
    >> Hi,
    >>
    >> the embedded C compiler that I (have to) use won't compile
    >> enum { f = +1 };
    >> giving an error message on the tune of "invalid constant
    >> expression", although it is fine with either of
    >> enum { f = 1 };
    >> enum { f = -1 };
    >>
    >> It similarly refuses
    >> int g[ +1 ];
    >> but accepts (including in a global context)
    >> int h = +1;
    >>
    >> Has there EVER been a C definition where unary + is not
    >> allowed in constant expressions ?

    >
    > Original K&R C had no unary + operator at all; it was added
    > in the 1989 ANSI Standard. It seems your compiler is in a sort
    > of half-way position: It obviously recognizes unary + in some
    > contexts, but not in others.


    So if a compiler refuses

    int g[ 1 ? 2 : 3 ]; /* invalid constant expression */

    it's in a halfway position with regard to supporting the ternary
    operator?
    Kaz Kylheku, Jan 1, 2010
    #4
  5. Francois Grieu

    Eric Sosman Guest

    On 1/1/2010 4:52 PM, Kaz Kylheku wrote:
    > On 2010-01-01, Eric Sosman<> wrote:
    >> [...]
    >> Original K&R C had no unary + operator at all; it was added
    >> in the 1989 ANSI Standard. It seems your compiler is in a sort
    >> of half-way position: It obviously recognizes unary + in some
    >> contexts, but not in others.

    >
    > So if a compiler refuses
    >
    > int g[ 1 ? 2 : 3 ]; /* invalid constant expression */
    >
    > it's in a halfway position with regard to supporting the ternary
    > operator?


    <Shrug.> Sure, why not? But it's hard to see how that
    compiler could claim "C-ness" under any widespread definition,
    since the ternary operator has been part of the language since
    before the publication of K&R in 1978. (Still, people will
    hang the label "C" on practically any compiler that accepts
    semicolons. I once encountered a compiler for a "C" without
    structs, unions, floating-point, and multidimensional arrays!)

    The weird thing about the O.P.'s situation is that his
    compiler clearly recognizes unary + as an operator (hence, it's
    post-K&R), but somehow doesn't understand that +constant is a
    constant expression (as any ANSI-and-beyond compiler must).
    His compiler seems to be post-K&R but pre-ANSI; that's what I
    meant by "half-way."

    (There's also the possibility that the compiler is supposed
    to be ANSI- or even post-ANSI-conforming, but has a bug. One of
    the very first lessons I was taught was "The bug's in your code,
    not in the compiler," but early lessons sometimes oversimplify.)

    --
    Eric Sosman
    lid
    Eric Sosman, Jan 1, 2010
    #5
  6. Francois Grieu

    Eric Sosman Guest

    On 1/1/2010 4:48 PM, Kaz Kylheku wrote:
    > [...]
    > Whether or not an expression is constant in C depends on which operators
    > it uses, not only a matter of what kinds of operands. For instance
    > 1 ? 2 : 3 is not a constant expression, because it uses the ternary operator,
    > even though all of the subexpressions are constants.


    Chapter and verse?

    The grammar for constant-expression (6.6) produces the same
    sentential forms as conditional-expression, which (6.5.15) is
    either a logical-OR-expression or an application of the ternary
    operator. Hence, the syntax of constant-expression allows the
    presence of ternary operators in the expression.

    Semantically, some operators are forbidden in various types
    of constant expressions: function calls, assignments and so on.
    The ternary operator is not on the prohibited list for any of
    the sub-types of constant-expression. (Or if it is, the high
    school P.E. teacher who told me "You'll go blind" was right.)

    Where do you find a ban on the ternary operator?

    --
    Eric Sosman
    lid
    Eric Sosman, Jan 1, 2010
    #6
  7. Francois Grieu

    Kaz Kylheku Guest

    On 2010-01-01, Eric Sosman <> wrote:
    > Semantically, some operators are forbidden in various types
    > of constant expressions: function calls, assignments and so on.
    > The ternary operator is not on the prohibited list for any of
    > the sub-types of constant-expression. (Or if it is, the high
    > school P.E. teacher who told me "You'll go blind" was right.)
    >
    > Where do you find a ban on the ternary operator?


    I seem to recall this (falsely?) from C90. Alas, I lost my hard copy.
    Kaz Kylheku, Jan 1, 2010
    #7
  8. Francois Grieu

    jacob navia Guest

    Eric Sosman a écrit :
    > On 1/1/2010 4:52 PM, Kaz Kylheku wrote:
    >> On 2010-01-01, Eric Sosman<> wrote:
    >>> [...]
    >>> Original K&R C had no unary + operator at all; it was added
    >>> in the 1989 ANSI Standard. It seems your compiler is in a sort
    >>> of half-way position: It obviously recognizes unary + in some
    >>> contexts, but not in others.

    >>
    >> So if a compiler refuses
    >>
    >> int g[ 1 ? 2 : 3 ]; /* invalid constant expression */
    >>
    >> it's in a halfway position with regard to supporting the ternary
    >> operator?

    >
    > <Shrug.> Sure, why not? But it's hard to see how that
    > compiler could claim "C-ness" under any widespread definition,
    > since the ternary operator has been part of the language since
    > before the publication of K&R in 1978. (Still, people will
    > hang the label "C" on practically any compiler that accepts
    > semicolons. I once encountered a compiler for a "C" without
    > structs, unions, floating-point, and multidimensional arrays!)
    >


    Look:

    file foo.c
    int m = 12 < 43 ? 56 : 87;
    EOF


    This file compiles without warnings in MSVC, lcc-win, and gcc

    This one too:

    int m[12 < 43 ? 12 : 43 ];


    What I can't support from this guy (Kaz) is the ARROGANCE he displays.
    jacob navia, Jan 1, 2010
    #8
  9. Francois Grieu

    jacob navia Guest

    Kaz Kylheku a écrit :
    >
    > So if a compiler refuses
    >
    > int g[ 1 ? 2 : 3 ]; /* invalid constant expression */
    >
    > it's in a halfway position with regard to supporting the ternary
    > operator?


    Look:

    file foo.c
    int m = 12 < 43 ? 56 : 87;
    EOF


    This file compiles without warnings in MSVC, lcc-win, and gcc

    This one too:

    int m[12 < 43 ? 12 : 43 ];


    What I can't support from you is the ARROGANCE you display. As if you would
    know all, speaking "ex cathedra".

    You are just wrong Kaz.
    jacob navia, Jan 1, 2010
    #9
  10. Francois Grieu

    Kaz Kylheku Guest

    On 2010-01-01, jacob navia <> wrote:
    > Kaz Kylheku a écrit :
    >>
    >> So if a compiler refuses
    >>
    >> int g[ 1 ? 2 : 3 ]; /* invalid constant expression */
    >>
    >> it's in a halfway position with regard to supporting the ternary
    >> operator?

    >
    > Look:
    >
    > file foo.c
    > int m = 12 < 43 ? 56 : 87;
    > EOF


    My bad. It's the comma operator I was thinking of, not ternary.

    A comma operator is not a constant expression in C90, and still not in C99.

    So int g[1, 2]; isn't valid.

    I knew there was some operator which renders a de-facto constant
    expression non-constant; I just didn't remember its identity correctly.
    Kaz Kylheku, Jan 1, 2010
    #10
  11. Francois Grieu

    Thad Smith Guest

    Francois Grieu wrote:
    > the embedded C compiler that I (have to) use won't compile
    > enum { f = +1 };
    > giving an error message on the tune of "invalid constant
    > expression", although it is fine with either of
    > enum { f = 1 };
    > enum { f = -1 };
    >
    > It similarly refuses
    > int g[ +1 ];
    > but accepts (including in a global context)
    > int h = +1;
    >
    > Has there EVER been a C definition where unary + is not
    > allowed in constant expressions ?
    > Or a common parser with this odd characteristic ?


    That isn't terribly surprising for embedded C compilers. My impression
    is that sometimes the compiler is written with too many special cases,
    in which general support, in this case constant expression, is lost in
    less-frequency-used cases. The compiler I am using gives an error for

    struct S {
    int x: 2*3;
    };


    --
    Thad
    Thad Smith, Jan 2, 2010
    #11
  12. Kaz Kylheku <> writes:
    > On 2010-01-01, Eric Sosman <> wrote:
    >> Semantically, some operators are forbidden in various types
    >> of constant expressions: function calls, assignments and so on.
    >> The ternary operator is not on the prohibited list for any of
    >> the sub-types of constant-expression. (Or if it is, the high
    >> school P.E. teacher who told me "You'll go blind" was right.)
    >>
    >> Where do you find a ban on the ternary operator?

    >
    > I seem to recall this (falsely?) from C90. Alas, I lost my hard copy.


    My soft copy disagrees with your memory. The ternary operator is
    permitted in constant expressions in C90.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 2, 2010
    #12
  13. Kaz Kylheku wrote:
    > On 2010-01-01, Francois Grieu <> wrote:
    >> the embedded C compiler that I (have to) use won't compile
    >> enum { f = +1 };
    >> giving an error message on the tune of "invalid constant
    >> expression", although it is fine with either of
    >> enum { f = 1 };
    >> enum { f = -1 };
    >>
    >> It similarly refuses
    >> int g[ +1 ];
    >> but accepts (including in a global context)
    >> int h = +1;

    (..)
    >
    > You should report the issue to your compile vendor, but it's hardly
    > a show stopper with no workaround. Why are you using unary plus at all?


    // check there a some things and count them
    enum { number_of_things =
    #define THING(name,value) +1
    #include "things.h"
    #undef THING
    };

    with the file things.h similar to
    THING(blue,12)
    THING(pink,17)

    My workaround is:
    // count the things
    enum { number_of_things = 0
    #define THING(name,value) +1
    #include "things.h"
    #undef THING
    };
    // error if no thing
    extern char error_no_thing[ number_of_things>0 ?1:-1 ];


    Francois Grieu
    Francois Grieu, Jan 2, 2010
    #13
  14. Eric Sosman wrote :
    > Original K&R C had no unary + operator at all


    Ah, I did not know that. It could explain some of the
    issue: start from a K&R compiler, add unary + in the
    parsing of expressions, but not constant expressions.

    FWIW, the compiler vendor is in business since 1983, now
    uses C89 as reference, and in 2009 added some C99 traces:
    enum { f = 1, }

    Francois Grieu
    Francois Grieu, Jan 2, 2010
    #14
    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.

Share This Page