lvalue cast

M

Martijn

Hi,

I recently updated my version of gcc (to gcc version 3.4.2
(mingw-special) ), and I get a warning I am not too sure about how to best
solve:

warning: use of cast expressions as lvalues is deprecated

The code that invokes this warning has to do with PIDLs (pointer to item id
list, which are a Windows thing and not too important really). The problem
is that I have a pointer to a structure (typedef'd to ITEMIDLIST) and in
order to access some data I have to move over a certain amount of bytes (the
pointer really points to an array with arbitrary-sized memory blocks, and
the structure is just a way to interface those blocks), so this is what I
did:

ITEMIDLIST* pidl;
int offset;

...

(char*)pidl += offset;

What can I do to fix the warning? Preferebly without the use of an extra
variable (e.g. a char*).

Thanks,
 
R

Richard Tobin

Martijn said:
ITEMIDLIST* pidl;
int offset;

...

(char*)pidl += offset;

You could do "pidl = (ITEMIDLIST*)(((char *)pidl) + offset)".

Someone else will probably address thet portability issues with this
sort of thing. I assume you are aware of alignment issues.

-- Richard
 
S

SM Ryan

# Hi,
#
# I recently updated my version of gcc (to gcc version 3.4.2
# (mingw-special) ), and I get a warning I am not too sure about how to best
# solve:
#
# warning: use of cast expressions as lvalues is deprecated
#
# The code that invokes this warning has to do with PIDLs (pointer to item id
# list, which are a Windows thing and not too important really). The problem
# is that I have a pointer to a structure (typedef'd to ITEMIDLIST) and in
# order to access some data I have to move over a certain amount of bytes (the
# pointer really points to an array with arbitrary-sized memory blocks, and
# the structure is just a way to interface those blocks), so this is what I
# did:
#
# ITEMIDLIST* pidl;
# int offset;
#
# ...
#
# (char*)pidl += offset;
#
# What can I do to fix the warning? Preferebly without the use of an extra
# variable (e.g. a char*).

To cast an lvalue V of type S to an lvalue of type T,
you can do something like

*(T*)&V

lvalue S V
pointer to S &V
pointer to T (T*)&V
lvalue T *(T*)&V
 
P

pete

Martijn said:
Hi,

I recently updated my version of gcc (to gcc version 3.4.2
(mingw-special) ), and I get a warning I am not too sure about how to best
solve:

warning: use of cast expressions as lvalues is deprecated

The code that invokes this warning has to do with PIDLs (pointer to item id
list, which are a Windows thing and not too important really). The problem
is that I have a pointer to a structure (typedef'd to ITEMIDLIST) and in
order to access some data I have to move over a certain amount of bytes (the
pointer really points to an array with arbitrary-sized memory blocks, and
the structure is just a way to interface those blocks), so this is what I
did:

ITEMIDLIST* pidl;
int offset;

...

(char*)pidl += offset;

What can I do to fix the warning?
Preferebly without the use of an extra variable (e.g. a char*).

pidl = (ITEMIDLIST *)((char *)pidl + offset);
 
K

Keith Thompson

Martijn said:
I recently updated my version of gcc (to gcc version 3.4.2
(mingw-special) ), and I get a warning I am not too sure about how to best
solve:

warning: use of cast expressions as lvalues is deprecated

That's an odd warning. The use of cast expressions as lvalues isn't
just deprecated; it's illegal (a constraint violation). It's been
illegal at least since C90; I don't know whether it might have been
allowed before that.

[...]
ITEMIDLIST* pidl;
int offset;

...

(char*)pidl += offset;

What can I do to fix the warning? Preferebly without the use of an extra
variable (e.g. a char*).

I think this should do it:

pidl = (ITEMIDLIST*)((char*)pidl + offset);

But you might find it cleaner to step through the array using a char*,
and convert the char* value to the appropriate type when you use it.
 
M

Martijn

Keith said:

[snipped]
I think this should do it:

pidl = (ITEMIDLIST*)((char*)pidl + offset);

Thanks everyone for the response. The thing that threw me of was +=. I of
course intended to cast just the right hand of the = sign, but using +=
kind-of made that rvalue an lvalue. Now I feel kinda silly askin' this,
especially with the experience I've had programming C ...

[snipped a little more]

Thanks again,
 
P

pete

Martijn said:
The thing that threw me of was +=.

(x) += (y)
means exactly
(x) = (x) + (y)
for any values of x and y.

If you have
unsigned short us = USHRT_MAX;
then
++us;
yields undefined behavior, if USHRT_MAX == INT_MAX.
 
C

Christian Bau

SM Ryan said:
# Hi,
#
# I recently updated my version of gcc (to gcc version 3.4.2
# (mingw-special) ), and I get a warning I am not too sure about how to best
# solve:
#
# warning: use of cast expressions as lvalues is deprecated
#
# The code that invokes this warning has to do with PIDLs (pointer to item id
# list, which are a Windows thing and not too important really). The problem
# is that I have a pointer to a structure (typedef'd to ITEMIDLIST) and in
# order to access some data I have to move over a certain amount of bytes (the
# pointer really points to an array with arbitrary-sized memory blocks, and
# the structure is just a way to interface those blocks), so this is what I
# did:
#
# ITEMIDLIST* pidl;
# int offset;
#
# ...
#
# (char*)pidl += offset;
#
# What can I do to fix the warning? Preferebly without the use of an extra
# variable (e.g. a char*).

To cast an lvalue V of type S to an lvalue of type T,
you can do something like

*(T*)&V

lvalue S V
pointer to S &V
pointer to T (T*)&V
lvalue T *(T*)&V

That has the distinct disadvantage of invoking undefined behavior if you
use V later (with a few exceptions). The original would hopefully have
defined behavior in the gcc language (which is not quite the same as the
C language).

Consider an implementation where sizeof (ITEMIDLIST *) != sizeof (char
*). Your code is likely to cause trouble. With gcc I would hope that it
does something reasonable in that case.
 
C

Christian Bau

Keith Thompson said:
That's an odd warning. The use of cast expressions as lvalues isn't
just deprecated; it's illegal (a constraint violation). It's been
illegal at least since C90; I don't know whether it might have been
allowed before that.

It is legal and deprectated in the language implemented by the gcc
compiler with default settings, which is not quite the same as C.
 
R

Richard Tobin

Keith Thompson said:
That's an odd warning. The use of cast expressions as lvalues isn't
just deprecated; it's illegal (a constraint violation).

Presumably the gcc extension is deprecated.
illegal at least since C90; I don't know whether it might have been
allowed before that.

It was allowed in some drafts of ANSI C.

-- Richard
 
S

SM Ryan

# In article <[email protected]>,
#
# > # Hi,
# > #
# > # I recently updated my version of gcc (to gcc version 3.4.2
# > # (mingw-special) ), and I get a warning I am not too sure about how to best
# > # solve:
# > #
# > # warning: use of cast expressions as lvalues is deprecated
# > #
# > # The code that invokes this warning has to do with PIDLs (pointer to item id
# > # list, which are a Windows thing and not too important really). The problem
# > # is that I have a pointer to a structure (typedef'd to ITEMIDLIST) and in
# > # order to access some data I have to move over a certain amount of bytes (the
# > # pointer really points to an array with arbitrary-sized memory blocks, and
# > # the structure is just a way to interface those blocks), so this is what I
# > # did:
# > #
# > # ITEMIDLIST* pidl;
# > # int offset;
# > #
# > # ...
# > #
# > # (char*)pidl += offset;
# > #
# > # What can I do to fix the warning? Preferebly without the use of an extra
# > # variable (e.g. a char*).
# >
# > To cast an lvalue V of type S to an lvalue of type T,
# > you can do something like
# >
# > *(T*)&V
# >
# > lvalue S V
# > pointer to S &V
# > pointer to T (T*)&V
# > lvalue T *(T*)&V
#
# That has the distinct disadvantage of invoking undefined behavior if you
# use V later (with a few exceptions). The original would hopefully have
# defined behavior in the gcc language (which is not quite the same as the
# C language).
#
# Consider an implementation where sizeof (ITEMIDLIST *) != sizeof (char
# *). Your code is likely to cause trouble. With gcc I would hope that it
# does something reasonable in that case.

Unable to divine the exact intention of the programmer, I don't really
know if he wants (*(T*)&V)++ or *(T*)&(V++) or something else, but since
V refers to any lvalue expression rather than just a variable name, I
decided a general wa to cast an lvalue and let him decide how to apply
it in his case.
 
S

SM Ryan

# It is legal and deprectated in the language implemented by the gcc
# compiler with default settings, which is not quite the same as C.

Wrong answer. It's not quite the same as ANSI C, but because ANSI
doesn't have an exclusive legal trademark on the capitialised
third letter of the alphabet, what gcc accepts is still a C dialect.

Lack of precision and bad implicit assumptions make for lousy
programs.
 
C

Christian Bau

SM Ryan said:
# It is legal and deprectated in the language implemented by the gcc
# compiler with default settings, which is not quite the same as C.

Wrong answer. It's not quite the same as ANSI C, but because ANSI
doesn't have an exclusive legal trademark on the capitialised
third letter of the alphabet, what gcc accepts is still a C dialect.

Wrong answer. About the first line in the ISO/IEC 9899 Standard says:

"This International Standard specifies the form and establishes the
interpretation of programs written in the C programming language."

There are no dialects of C. There are languages that have some
similarity to C, like the language accepted by the gcc compiler with
default settings, or the C++ language, or the Java language, but they
are not C and they are not dialects of C.
Lack of precision and bad implicit assumptions make for lousy
programs.

I can let that stand.
 
S

SM Ryan

# In article <[email protected]>,
#
# >
# > # It is legal and deprectated in the language implemented by the gcc
# > # compiler with default settings, which is not quite the same as C.
# >
# > Wrong answer. It's not quite the same as ANSI C, but because ANSI
# > doesn't have an exclusive legal trademark on the capitialised
# > third letter of the alphabet, what gcc accepts is still a C dialect.
#
# Wrong answer. About the first line in the ISO/IEC 9899 Standard says:

Doesn't matter what they claim. Unless they have a trademark on "C",
they don't have exclusive definition of the language. It makes as much
sense as Sony claiming only they manufacture portable cassette players.

If you want to see the distinction, look at Ada. DoD did get a
trademark on that language name, so they can talk about _the_ Ada.

# There are no dialects of C. There are languages that have some
# similarity to C, like the language accepted by the gcc compiler with

That will come as a shock to Kernighan and Ritchie, that the language
they were using and writing about for so many years wasn't really C.

# > Lack of precision and bad implicit assumptions make for lousy
# > programs.
#
# I can let that stand.

Try learning it.
 
K

Keith Thompson

[[
Stupid deliberately obnoxious '#' quoting character fixed yet
again. Please stop doing that. Whatever point you're trying to
make, if you haven't made it by now, you never will.
]]

SM Ryan said:
Doesn't matter what they claim. Unless they have a trademark on "C",
they don't have exclusive definition of the language. It makes as much
sense as Sony claiming only they manufacture portable cassette players.

If you want to see the distinction, look at Ada. DoD did get a
trademark on that language name, so they can talk about _the_ Ada.

The name "Ada" is no longer trademarked.

In this newsgroup, by general consensus, an unqualified reference to
"C" refers to the language as defined by the current ISO standard, or
to the previous one which is still in common use. Historically, it
referred to previous versions of the language from before the first
ANSI standard (the language described in K&R1 or previous versions).
I doubt that K and R themselves would disagree with this.

If you want to be understood, you can either follow common usage or
make it clear that you're talking about something else (e.g., by using
the phrase "GNU C" rather than "C" to refer to a language that
includes the extensions implemented by gcc).

Having a standard is a good thing. Ignoring it, by pretending that
non-standard languages are "C", undermines the whole purpose of having
a standard.
That will come as a shock to Kernighan and Ritchie, that the language
they were using and writing about for so many years wasn't really C.

It was then, because there was no standard yet. The language that
used "=-" as an assignment operator is called C only historically; no
modern correct C compiler will decrement x in response to "x =- 1;".
 
S

SM Ryan

# The name "Ada" is no longer trademarked.

Shows how much I pay attention to DoD.

# In this newsgroup, by general consensus, an unqualified reference to
# "C" refers to the language as defined by the current ISO standard, or

That's not what Christian wrote. He makes a flat out, absolute statement
that ANSI C and only ANSI C is "C" and that all other dialects (which
would have have to include what K+R 1 described) are not "C". That's not
about qualified or unqualified references; he makes an absolute statement
in all contexts which is false.

I'm not part of your consensus. When I wish to be specific, I am specific
and write out ANSI C. It's not hard to type.

# Having a standard is a good thing. Ignoring it, by pretending that
# non-standard languages are "C", undermines the whole purpose of having
# a standard.

ANSI probably has a trademark on "ANSI". They can only claim ownership
of "ANSI C", not "C". Nobody owns "C", and nobody can declare what is
or is not C, only ANSI C, or gnu C, or K+R C, or ...

Now what was it Dijkstra said about mastery of language?
 
R

Richard Tobin

SM Ryan said:
Doesn't matter what they claim. Unless they have a trademark on "C",
they don't have exclusive definition of the language.

Even if they had a trademark, it wouldn't give them control of the
truth, only of the use of the name in commercial contexts. The fact
that "Coke" is a trademark doens't make it true that it's "the real
thing", and nothing stops me putting up a sign saying "free Coke" and
giving people Pepsi.

-- 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,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top