Compiler Issue

C

cyber citizen

Hi Folks,

We are encountering the following code issue on compiler susch as "xlc","gcc" but "icc" passes it successfully.

Sample code:
int main(void)
{
typedef unsigned char oratext;
typedef oratext text;

oratext c[2];
oratext * c_ptr = c;

text ** c_pptr;

c_pptr = &(oratext *)c_ptr;
}

Error:
"a.c", line 11.11: 1506-017 (S) Operand of address operator must be an lvalue or function designator.

It seems the compiler is unable to resolve all the addresses in its single pass. If we split this into to steps it works.

Modified code:
int main(void)
{
typedef unsigned char oratext;
typedef oratext text;

oratext c[2];
oratext * c_ptr = c;
text * c_ptr1;

c_ptr1 = (oratext *)c_ptr;

text ** c_pptr;

c_pptr = &c_ptr1;

}

Is this a known issue? are there any other work arounds for such a problem?

TIA

Himanshu
 
I

Ian Collins

cyber said:
Hi Folks,

We are encountering the following code issue on compiler susch as
"xlc","gcc" but "icc" passes it successfully.

Sample code:
int main(void)
{
typedef unsigned char oratext;
typedef oratext text;

oratext c[2];
oratext * c_ptr = c;

text ** c_pptr;

c_pptr = &(oratext *)c_ptr;

Why cast to an oratext* when c_ptr already is one?

c_pptr = &c_ptr;
 
S

spibou

cyber said:
Hi Folks,

We are encountering the following code issue on compiler susch as "xlc","gcc" but "icc" passes it successfully.

Sample code:
int main(void)
{
typedef unsigned char oratext;
typedef oratext text;

oratext c[2];
oratext * c_ptr = c;

text ** c_pptr;

c_pptr = &(oratext *)c_ptr;
}

Error:
"a.c", line 11.11: 1506-017 (S) Operand of address operator must be an lvalue or function designator.

It seems the compiler is unable to resolve all the addresses in its single pass. If we split this into to steps it works.

The Sun compiler gives "warning: a cast does not yield an lvalue".
Same for lint. This suggests to me that the compiler does not think
that there is an address to be resolved. It makes sense if you think
about it. If c is a char for example and I write &(int)c then what
address would I expect to be returned which can be used in a useful
manner as a pointer to int ? I don't think it's possbile.

Of course I noticed that when you write c_pptr = &(oratext *)c_ptr
c_ptr is already a pointer to oratext but so what ? Would you expect
the compiler to notice that the cast is superfluous and treat the whole
expression as c_pptr = &c_ptr ? I wouldn't. Why are you using a cast
anyway ?

By the way the following simpler piece of code yields a similar
warning:

int main() {
int a , *p , **p1 ;

p = &a ;
p1 = &(int *)p ;
return 0 ;
}

It was an unpleasant surprise to me that splint does not give a warning
in either case.
Is this a known issue? are there any other work arounds for such a problem?

I hadn't come across it before but I wasn't surprised. I don't consider
it a
problem either. Just loose the superfluous cast and the "problem" is
solved.

Spiros Bousbouras
 
C

cyber citizen

Ian said:
cyber said:
Hi Folks,

We are encountering the following code issue on compiler susch as
"xlc","gcc" but "icc" passes it successfully.

Sample code:
int main(void)
{
typedef unsigned char oratext;
typedef oratext text;

oratext c[2];
oratext * c_ptr = c;

text ** c_pptr;

c_pptr = &(oratext *)c_ptr;


Why cast to an oratext* when c_ptr already is one?

c_pptr = &c_ptr;

I know the type cast there in superfluous. How ever whats the difference in c_pptr = &(oratext *)c_ptr; and _pptr = &c_ptr;

Regards
Himanshu
 
I

Ian Collins

cyber said:
Ian said:
cyber said:
Hi Folks,

We are encountering the following code issue on compiler susch as
"xlc","gcc" but "icc" passes it successfully.

Sample code:
int main(void)
{
typedef unsigned char oratext;
typedef oratext text;

oratext c[2];
oratext * c_ptr = c;

text ** c_pptr;

c_pptr = &(oratext *)c_ptr;



Why cast to an oratext* when c_ptr already is one?

c_pptr = &c_ptr;

I know the type cast there in superfluous. How ever whats the difference
in c_pptr = &(oratext *)c_ptr; and _pptr = &c_ptr;
The compiler warning says it all, the cast doesn't yield an lvalue.
 
R

Richard Heathfield

cyber citizen said:
Hi Folks,

We are encountering the following code issue on compiler susch as
"xlc","gcc" but "icc" passes it successfully.

Sample code:
int main(void)
{
typedef unsigned char oratext;
typedef oratext text;

oratext c[2];
oratext * c_ptr = c;

text ** c_pptr;

c_pptr = &(oratext *)c_ptr;
}

Error:
"a.c", line 11.11: 1506-017 (S) Operand of address operator must be an
lvalue or function designator.

The address operator is &. It yields an address. Objects have addresses, but
mere values don't. &4, for example, is meaningless. So is &NULL.

(oratext *) is a cast. Casts are nearly always wrong, and the places where
they're right and hardly ever the places you'd expect. This is one of those
wrong places. What you're doing is trying to convert an oratext * into an
oratext * - an utterly pointless conversion, whose sole effect in this case
is to convert an object (which you might reasonably have passed to &) into
a value (which you can't).

The solution is simple: remove the cast.

c_pptr = &c_ptr;
 
F

Frederick Gotham

cyber citizen posted:

c_pptr = &(oratext *)c_ptr;


Do all explicit casts result in an R-value, even if it could conceivably be
possible to yield an L-value? E.g.:

int main(void)
{
int i;


(unsigned)i = 55; /* Never an L-value */
}


Thus, the programmer would have to write:


*(unsigned *)&i = 55;
 
R

Richard Heathfield

Frederick Gotham said:
cyber citizen posted:




Do all explicit casts result in an R-value,

Yes. (Incidentally, a cast is an explicit conversion, so an explicit cast is
an explicit explicit conversion!)

3.3.4 of C89 says:
"Preceding an expression by a parenthesized type name converts the
value of the expression to the named type."

So it is the value itself that is converted, and this conversion yields a
value, not an object.
even if it could conceivably
be possible to yield an L-value?

Even then.
E.g.:

int main(void)
{
int i;


(unsigned)i = 55; /* Never an L-value */
}

foo.c:6: warning: ANSI C forbids use of cast expressions as lvalues
foo.c:7: warning: control reaches end of non-void function
Thus, the programmer would have to write:


*(unsigned *)&i = 55;

Yes. Or, more simply: i = 55;
 
I

Ian Collins

Richard said:
foo.c:6: warning: ANSI C forbids use of cast expressions as lvalues

Bit of a strange warning, if ANSI C forbids the use of cast expressions
as lvalues, shouldn't this be an error?

Certainly is in C++.
 
C

Chris Dollin

Ian said:
Bit of a strange warning, if ANSI C forbids the use of cast expressions
as lvalues, shouldn't this be an error?

I'd imagine it's a constraint violation, which requires a diagnostic,
and "foo.c:6: warning: ANSI C forbids use of cast expressions as lvalues"
looks like a diagnostic to me.

I don't believe the standard distinguishes between "warnings" and "errors",
nor requires [1] that a constraint violation implies that no object code
is generated.
Certainly is in C++.

C++ requires that errors result in compilation failure and no object
module (or whatever the moral equivalent is)?

[1] Except for the #error directive?
 
R

Richard Heathfield

Chris Dollin said:
Ian said:
Bit of a strange warning, if ANSI C forbids the use of cast expressions
as lvalues, shouldn't this be an error?

I'd imagine it's a constraint violation, which requires a diagnostic,
and "foo.c:6: warning: ANSI C forbids use of cast expressions as lvalues"
looks like a diagnostic to me.
Correct.

I don't believe the standard distinguishes between "warnings" and
"errors", nor requires [1] that a constraint violation implies that no
object code is generated.
Correct.
Certainly is in C++.

C++ requires that errors result in compilation failure and no object
module (or whatever the moral equivalent is)?
Off-topic.

[1] Except for the #error directive?

Correct.



"Now don't... be... sad... cos three out o' four ain't bad..."
 
R

Richard Bos

Chris Dollin said:
Ian said:
Bit of a strange warning, if ANSI C forbids the use of cast expressions
as lvalues, shouldn't this be an error?

I'd imagine it's a constraint violation, which requires a diagnostic,
and "foo.c:6: warning: ANSI C forbids use of cast expressions as lvalues"
looks like a diagnostic to me.

I don't believe the standard distinguishes between "warnings" and "errors",
nor requires [1] that a constraint violation implies that no object code
is generated.

True; what it does say is that _if_ a constraint is violated but the
program is (turned into an executable, c.q., and) run, it causes
undefined behaviour if the constraint-violating code is encountered.

Richard
 
G

Guest

Richard said:
Chris Dollin said:
Ian said:
Richard Heathfield wrote:

foo.c:6: warning: ANSI C forbids use of cast expressions as lvalues

Bit of a strange warning, if ANSI C forbids the use of cast expressions
as lvalues, shouldn't this be an error?

I'd imagine it's a constraint violation, which requires a diagnostic,
and "foo.c:6: warning: ANSI C forbids use of cast expressions as lvalues"
looks like a diagnostic to me.

I don't believe the standard distinguishes between "warnings" and "errors",
nor requires [1] that a constraint violation implies that no object code
is generated.

True; what it does say is that _if_ a constraint is violated but the
program is (turned into an executable, c.q., and) run, it causes
undefined behaviour if the constraint-violating code is encountered.

Does it actually say that the behaviour is undefined only if the
constraint-violating code is encountered? I would've thought it would
have u.b. regardless.
 
G

gw7rib

cyber said:
Hi Folks,

We are encountering the following code issue on compiler susch as "xlc","gcc" but "icc" passes it successfully.

Others have pointed out the problem, but it is perhaps worth seeing
what the "corrected" code does to understand the problem:
Sample code:
int main(void)
{
typedef unsigned char oratext;
typedef oratext text;

oratext c[2];
oratext * c_ptr = c;

text ** c_pptr;

c_pptr = &(oratext *)c_ptr;
}

This is presumably intended to make c_pptr point at c_ptr.
If we split this into to steps it works.

Modified code:
int main(void)
{
typedef unsigned char oratext;
typedef oratext text;

oratext c[2];
oratext * c_ptr = c;
text * c_ptr1;

c_ptr1 = (oratext *)c_ptr;

text ** c_pptr;

c_pptr = &c_ptr1;

}

And this makes c_pptr point at c_ptr1 - it doesn't make c_pptr point at
c_ptr. c_ptr1 isn't the same variable as c_ptr, it's a different
variable which currently has the same value.

If you want to make c_pptr point at c_ptr, you have to take its address
- not the address of something else.

Paul.
 
K

Keith Thompson

I don't believe the standard distinguishes between "warnings" and "errors",
nor requires [1] that a constraint violation implies that no object code
is generated.

True; what it does say is that _if_ a constraint is violated but the
program is (turned into an executable, c.q., and) run, it causes
undefined behaviour if the constraint-violating code is encountered.

Where does it say that?

See the recent discussion in comp.std.c, "Does a constraint violation
imply undefined behavior?".
 
I

Ian Collins

Chris said:
Ian Collins wrote:

Bit of a strange warning, if ANSI C forbids the use of cast expressions
as lvalues, shouldn't this be an error?


I'd imagine it's a constraint violation, which requires a diagnostic,
and "foo.c:6: warning: ANSI C forbids use of cast expressions as lvalues"
looks like a diagnostic to me.

I don't believe the standard distinguishes between "warnings" and "errors",
nor requires [1] that a constraint violation implies that no object code
is generated.
I still can't see why. Maybe my hopes for C99 addressing these issues
were too high.
C++ requires that errors result in compilation failure and no object
module (or whatever the moral equivalent is)?
It's an error; you can't take the address of a value.
 
R

Richard Bos

Keith Thompson said:
I don't believe the standard distinguishes between "warnings" and "errors",
nor requires [1] that a constraint violation implies that no object code
is generated.

True; what it does say is that _if_ a constraint is violated but the
program is (turned into an executable, c.q., and) run, it causes
undefined behaviour if the constraint-violating code is encountered.

Where does it say that?

I keep mixing this up.

It is a "shall" _outside_ a constraint which explicitly causes UB when
violated.

OTOH, code that violates a constraint usually (always?) has no
explicitly defined behaviour, so it has UB by default. For example,
there's a Constraint that says that the size in an array declarator
shall not be zero; and there is no defined behaviour that says what
happens when it _is_ zero; therefore, declaring an array of zero size
has undefined behaviour.

Richard
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top