+1 an invalid constant expression

F

Francois Grieu

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
 
E

Eric Sosman

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 ...
 
K

Kaz Kylheku

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?
 
K

Kaz Kylheku

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?
 
E

Eric Sosman

[...]
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.)
 
E

Eric Sosman

[...]
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?
 
K

Kaz Kylheku

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.
 
J

jacob navia

Eric Sosman a écrit :
[...]
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.
 
J

jacob navia

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.
 
K

Kaz Kylheku

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.
 
T

Thad Smith

Francois said:
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;
};
 
K

Keith Thompson

Kaz Kylheku said:
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.
 
F

Francois Grieu

Kaz said:
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
 
F

Francois Grieu

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top