(cast)void* Help....please! 
Author Message
 (cast)void* Help....please!

Hi,

Could someone tell me if cast void pointers are not lvalues in C++?

According to my MSVC++ compiler (version 4.1), you can't do what I'm doing
in the example below, it gave me an error on the highlighted line, saying

"++ operator needs an lvalue"

If the file is compiled as a '.C' file, it works, but it won't compile as
a '.CPP'!

The example works fine in both modes on a (pretty old) version of Borland
Turbo C++.

Is this a Microsoft specific thing?

E-Mail or post (please!).

--------------------------

//-------------------------  BEGIN EXAMPLE -------------------------
// This code is only provided as an example, the code it actually
// appeared in is too big to post.

#define MaxStructures   10

typedef struct tagMyStruct {

        int     x,y,z;

Quote:
} MyStruct,*MyStructPtr;

void    main()
{

        MyStruct        TestStruct[ MaxStructures ];

        MyStructPtr     P = &TestStruct[0];

        void    *vPtr;
        int     i;

        vPtr = (MyStructPtr)P;

        for (i = 0; i < MaxStructures; i++)
        {
                ((MyStructPtr)vPtr)->x = i;
                ((MyStructPtr)vPtr)->y = i;
                ((MyStructPtr)vPtr)->z = i;

                ((MyStructPtr)vPtr)++;  //   <----- THIS LINE *******
        }

Quote:
}



Sat, 26 Dec 1998 03:00:00 GMT  
 (cast)void* Help....please!

Quote:

> Hi,

> Could someone tell me if cast void pointers are not lvalues in C++?

> According to my MSVC++ compiler (version 4.1), you can't do what I'm doing
> in the example below, it gave me an error on the highlighted line, saying

> "++ operator needs an lvalue"

> If the file is compiled as a '.C' file, it works, but it won't compile as
> a '.CPP'!

> The example works fine in both modes on a (pretty old) version of Borland
> Turbo C++.

> Is this a Microsoft specific thing?

> E-Mail or post (please!).

> --------------------------

> //-------------------------  BEGIN EXAMPLE -------------------------
> // This code is only provided as an example, the code it actually
> // appeared in is too big to post.

> #define MaxStructures      10

> typedef struct tagMyStruct {

>    int     x,y,z;

> } MyStruct,*MyStructPtr;

> void       main()
> {

>    MyStruct        TestStruct[ MaxStructures ];

>    MyStructPtr     P = &TestStruct[0];

>    void    *vPtr;
>    int     i;

>    vPtr = (MyStructPtr)P;

>    for (i = 0; i < MaxStructures; i++)
>    {
>            ((MyStructPtr)vPtr)->x = i;
>            ((MyStructPtr)vPtr)->y = i;
>            ((MyStructPtr)vPtr)->z = i;

>            ((MyStructPtr)vPtr)++;  //   <----- THIS LINE *******
>    }

> }

No, it's not Microsoft specific.  The result of a cast is not an
lvalue.  Some compilers (including some Microsoft compilers) do allow
use of a cast as an lvalue for compatibility with some older
compilers.  Usually (read: if the compiler is not broken) this feature
is turned off if you specify the option to make the compiler comply
with the standard.

The correct (and safe) way to do what you want is

        vPtr = (MyStructPtr)vPtr + 1;

Michael M Rubenstein



Sun, 27 Dec 1998 03:00:00 GMT  
 (cast)void* Help....please!

Quote:

> Hi,

> Could someone tell me if cast void pointers are not lvalues in C++?

> According to my MSVC++ compiler (version 4.1), you can't do what I'm doing
> in the example below, it gave me an error on the highlighted line, saying

> "++ operator needs an lvalue"

> If the file is compiled as a '.C' file, it works, but it won't compile as
> a '.CPP'!

> The example works fine in both modes on a (pretty old) version of Borland
> Turbo C++.

> Is this a Microsoft specific thing?

> E-Mail or post (please!).

> --------------------------

> //-------------------------  BEGIN EXAMPLE -------------------------
> // This code is only provided as an example, the code it actually
> // appeared in is too big to post.

> #define MaxStructures   10

> typedef struct tagMyStruct {

>         int     x,y,z;

> } MyStruct,*MyStructPtr;

> void    main()
> {

>         MyStruct        TestStruct[ MaxStructures ];

>         MyStructPtr     P = &TestStruct[0];

>         void    *vPtr;
>         int     i;

>         vPtr = (MyStructPtr)P;

                 ^^^^^^^^^^^^^

This may have nothing to do with your C++ problem, but in the code presented
here the casting of P to type MyStructPtr is unneccessary. P is already type
MyStructPtr. Try "vPtr = P;".

Quote:

>         for (i = 0; i < MaxStructures; i++)
>         {
>                 ((MyStructPtr)vPtr)->x = i;
>                 ((MyStructPtr)vPtr)->y = i;
>                 ((MyStructPtr)vPtr)->z = i;

>                 ((MyStructPtr)vPtr)++;  //   <----- THIS LINE *******
>         }

> }

--
Al Bowers
Tampa, FL

http:www.gate.net/~abowers/index.html


Sun, 27 Dec 1998 03:00:00 GMT  
 (cast)void* Help....please!

[ snipped down to the bare essentials: ]
|> Could someone tell me if cast void pointers are not lvalues in C++?
|>
|>       void    *vPtr;
|>
|>               ((MyStructPtr)vPtr)++;  //   <----- THIS LINE *******

|No, it's not Microsoft specific.  The result of a cast is not an
|lvalue.  Some compilers (including some Microsoft compilers) do allow
|use of a cast as an lvalue for compatibility with some older
|compilers.  Usually (read: if the compiler is not broken) this feature
|is turned off if you specify the option to make the compiler comply
|with the standard.
|
|The correct (and safe) way to do what you want is
|
|        vPtr = (MyStructPtr)vPtr + 1;

True, all true, and it's quite readable too; but sometimes, if one
wants (and needs) to keep the same semantics as the postfix ++ operator,
one could use the (not so readable) solution:

                (*((MyStructPtr*)&vPtr))++;

kind regards,


--
Qgi nicws nt swaj ri rgw eufgr>



Mon, 28 Dec 1998 03:00:00 GMT  
 (cast)void* Help....please!


Quote:


> [ snipped down to the bare essentials: ]
> |> Could someone tell me if cast void pointers are not lvalues in C++?
> |>
> |>       void    *vPtr;
> |>
> |>               ((MyStructPtr)vPtr)++;  //   <----- THIS LINE *******

> |No, it's not Microsoft specific.  The result of a cast is not an
> |lvalue.  Some compilers (including some Microsoft compilers) do allow
> |use of a cast as an lvalue for compatibility with some older
> |compilers.  Usually (read: if the compiler is not broken) this feature
> |is turned off if you specify the option to make the compiler comply
> |with the standard.
> |
> |The correct (and safe) way to do what you want is
> |
> |        vPtr = (MyStructPtr)vPtr + 1;

> True, all true, and it's quite readable too; but sometimes, if one
> wants (and needs) to keep the same semantics as the postfix ++ operator,
> one could use the (not so readable) solution:

>            (*((MyStructPtr*)&vPtr))++;

> kind regards,

Right using current and past Microsoft C compilers.  But that isn't
portable since the standard deos not guarantee that all pointers have
the same representation or even the same size.  I'd strongly recommend
that if one needs the value before incrementing it one write more
verbose code.  Either save it in a variable or use something like

        ((vPtr = (MyStructPtr)vPtr + 1) - 1)

in an expression.  

Yuk, that's ugly.  On second thought, I'll just flatly recommend
saving in a variable.

Michael M Rubenstein



Mon, 28 Dec 1998 03:00:00 GMT  
 (cast)void* Help....please!

Quote:

> Could someone tell me if cast void pointers are not lvalues in C++?

Casts in general yield "rvalues" (as soon as you de-reference them you get
an "lvalue").

Quote:

> According to my MSVC++ compiler (version 4.1), you can't do what I'm doing
> in the example below, it gave me an error on the highlighted line, saying

> "++ operator needs an lvalue"

This is the problem!!  A cast yields an "rvalue".

Quote:

> If the file is compiled as a '.C' file, it works, but it won't compile as
> a '.CPP'!

> The example works fine in both modes on a (pretty old) version of Borland
> Turbo C++.

> Is this a Microsoft specific thing?

Probably not.  The standard says you can't do it.  Yes, many
implementations allow it to be done, but it isn't standard!!

Quote:

<<<deletia>>>
> typedef struct tagMyStruct {

>         int     x,y,z;

> } MyStruct,*MyStructPtr;

<<<deletia>>>
>         MyStruct        TestStruct[ MaxStructures ];

>         MyStructPtr     P = &TestStruct[0];

>         void    *vPtr;
<<<deletia>>>

>                 ((MyStructPtr)vPtr)++;  //   <----- THIS LINE *******

While this is "sometimes" acceptable to some compilers, it is NOT standard
ANSI style C.  Casting a pointer yields an "rvalue" which is NOT
modifiable with the "++" operator (according to the standard).

To properly do this, you need to assign things to and from a pointer.
Yes, it is clumsy, but the standard says so.  The other ting is that you
can't do arithmetic with a void pointer.  It can only be assigned.  One
can think of this as having 'void' with a 'sizeof' of zero.  Yes, the
standard says nothing about the 'sizeof' a void pointer, but it is a
convient way of thinking about it.  This makes the following 'useless':

void *pointer;
char *points_to_char;

/* Bad!! */
pointer[5] = 1234;
/* Bad as well */
points_to_char = pointer + 5;
/* Even worse!! */
pointer++;

Don't try this at home!  But, sometimes it does work.  There are "hacks"
in compilers (like gcc) that can treat 'sizeof' void as 1.

Have fun...

--
Tom Watson



Mon, 28 Dec 1998 03:00:00 GMT  
 (cast)void* Help....please!

|> > "++ operator needs an lvalue"
|>
|> This is the problem!!  A cast yields an "rvalue".

Actually, in C++ a cast to a reference type yields an lvalue.  However,
considering that the original poster chose an entirely inappropriate group
to post his question to, this is a moot point.  :-)

Regards,

--
/*-------------------------------------------------------------
Chris Engebretson // CSB - SED - Scientific Systems Development
United States Geological Survey   -   National Mapping Division
Mundt Federal Building, USGS EROS Data Center
Sioux Falls, SD 57198  http://edcwww.cr.usgs.gov/eros-home.html

-------------------------------------------------------------*/



Tue, 29 Dec 1998 03:00:00 GMT  
 (cast)void* Help....please!

Quote:

> #define MaxStructures   10
> typedef struct tagMyStruct {int x,y,z;} MyStruct,*MyStructPtr;

> void    main()
> {
>         MyStruct        TestStruct[ MaxStructures ];
>         MyStructPtr     P = &TestStruct[0];                              ^^^^^^^^^^^^^^

The address-of element zero is not necessary, use the following form...
          MyStructPtr     P = TestStruct;

Quote:
>         void    *vPtr;
>         int     i;

>         vPtr = (MyStructPtr)P;                  ^^^^^^^^^^^^^

The cast should be (void *)...P is already of type MyStructPtr.
          vPtr = (void *) P;

Actually the cast is not necessary since a void pointer can
be assigned any pointer type.
          vPtr = P;

Quote:

>         for (i = 0; i < MaxStructures; i++)
>         {
>                 ((MyStructPtr)vPtr)->x = i;
>                 ((MyStructPtr)vPtr)->y = i;
>                 ((MyStructPtr)vPtr)->z = i;
>                 ((MyStructPtr)vPtr)++;  //   <----- THIS LINE *******Change vPtr's cast above to correct this line.




Wed, 30 Dec 1998 03:00:00 GMT  
 (cast)void* Help....please!

Quote:


>> #define MaxStructures   10
>> typedef struct tagMyStruct {int x,y,z;} MyStruct,*MyStructPtr;

>> void    main()

I will not comment on this

Quote:
>> {
>>         MyStruct        TestStruct[ MaxStructures ];
>>         MyStructPtr     P = &TestStruct[0];                              ^^^^^^^^^^^^^^
>The address-of element zero is not necessary, use the following form...
>          MyStructPtr     P = TestStruct;

This is a matter of style. There is nothing wrong with using
"&TestStruct[0]". It _may_ be a sign of "mistrust", and should be
avoided as a such.

Quote:
>>         void    *vPtr;
>>         int     i;

>>         vPtr = (MyStructPtr)P;                  ^^^^^^^^^^^^^
>The cast should be (void *)...P is already of type MyStructPtr.
>      vPtr = (void *) P;
>Actually the cast is not necessary since a void pointer can
>be assigned any pointer type.
>      vPtr = P;

Correct, but I'd say the cast should be _avoided_ in this case.
This is a matter of style, too, but adding superfluous casts
can be dangerous sometimes.

Quote:

>>         for (i = 0; i < MaxStructures; i++)
>>         {
>>                 ((MyStructPtr)vPtr)->x = i;
>>                 ((MyStructPtr)vPtr)->y = i;
>>                 ((MyStructPtr)vPtr)->z = i;
>>                 ((MyStructPtr)vPtr)++;  //   <----- THIS LINE *******Change vPtr's cast above to correct this line.

How will any of the cast "above" affect this line? A cast expression is
not an lvalue, hence this cannot work.

                    vPtr = ((MyStructPtr)vPtr) + 1;

_will_ work. You need an lvalue as the operand of the autoincrement
operator.

Kurt

--
| Kurt Watzka                             Phone : +49-89-2180-6254



Thu, 31 Dec 1998 03:00:00 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. casting of struct element void pointer casting

2. (cast)void* Help....

3. Dereference void pointer help, xxgdb help please

4. Please help!!!!Please help!!!!Please help!!!!Please help!!!!Please help!!!!Please help!!!!Please help!!!!

5. from void (void*) to void (_cdecl*) (void*)

6. help please: void/ int func. decltns

7. Please help!!!!Please help!!!!Please help!!!!

8. Casting a pointer - please help.

9. Please help with casting

10. Error invalid cast. Please help

11. HELP WANTED with converting void* from malloc() to void far*

12. Casting pinning pointer to void *

 

 
Powered by phpBB® Forum Software