By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,750 Members | 1,221 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,750 IT Pros & Developers. It's quick & easy.

Compiler Issue

P: n/a
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
Jun 23 '06 #1
Share this Question
Share on Google+
16 Replies


P: n/a
cyber citizen wrote:
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;

--
Ian Collins.
Jun 23 '06 #2

P: n/a
cyber citizen wrote:
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

Jun 23 '06 #3

P: n/a
Ian Collins wrote:
cyber citizen wrote:
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
Jun 23 '06 #4

P: n/a
cyber citizen wrote:
Ian Collins wrote:
cyber citizen wrote:
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.

--
Ian Collins.
Jun 23 '06 #5

P: n/a
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;
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 23 '06 #6

P: n/a
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;
Jun 23 '06 #7

P: n/a
Frederick Gotham said:
cyber citizen posted:

c_pptr = &(oratext *)c_ptr;

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;

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 23 '06 #8

P: n/a
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?

Certainly is in C++.

--
Ian Collins.
Jun 23 '06 #9

P: n/a
Ian Collins wrote:
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.
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?

--
Chris "seeker" Dollin
"Who do you serve, and who do you trust?" /Crusade/

Jun 23 '06 #10

P: n/a
Chris Dollin said:
Ian Collins wrote:
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.


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

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 23 '06 #11

P: n/a
Chris Dollin <ch**********@hp.com> wrote:
Ian Collins wrote:
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.

Richard
Jun 23 '06 #12

P: n/a
Richard Bos wrote:
Chris Dollin <ch**********@hp.com> wrote:
Ian Collins wrote:
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.

Jun 23 '06 #13

P: n/a

cyber citizen wrote:
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.

Jun 23 '06 #14

P: n/a
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Chris Dollin <ch**********@hp.com> wrote:

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

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 23 '06 #15

P: n/a
Chris Dollin wrote:
Ian Collins wrote:

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.

I still can't see why. Maybe my hopes for C99 addressing these issues
were too high.
Certainly is in C++.

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.

--
Ian Collins.
Jun 23 '06 #16

P: n/a
Keith Thompson <ks***@mib.org> wrote:
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Chris Dollin <ch**********@hp.com> wrote:

[...]
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
Jun 26 '06 #17

This discussion thread is closed

Replies have been disabled for this discussion.