lvalue required as increment operand

B

Ben Pfaff

Roman Mashak said:
extern inline void copy(void *pSource, void *pDest, unsigned int dLength)
{
unsigned int dI;

for (dI = 0; dI < dLength; dI++) {

*((char *) pDest) = *((char *) pSource);
((char *) pDest)++; /* error */
((char *) pSource)++; /* error */
}
}

extern inline void copy(void *pSource_, void *pDest_, unsigned int dLength)
{
char *pSource = pSource_;
char *pDest = pDest_;
unsigned int dI;

for (dI = 0; dI < dLength; dI++) {
*pDest = *pSource;
pDest++;
pSource++; /* error */
}
}
 
E

Eric Sosman

Roman said:
Hello,

I'm porting code, previously compiled by IAR compiler, for ARM-gcc compiler.
This snippet results in error, posted in subject:

/*
* copies a structure in a buffer
* pSource Data to copy
* pDest Buffer in which to copy the data
*/
extern inline void copy(void *pSource, void *pDest, unsigned int dLength)
{
unsigned int dI;

for (dI = 0; dI < dLength; dI++) {

*((char *) pDest) = *((char *) pSource);
((char *) pDest)++; /* error */
((char *) pSource)++; /* error */
}
}

As I understand, casting ends up with 'rvalue', and '++' or any other
operations can't be applied to rvalue. So, what is the proper solution here?
I'm unable to find a way :(

Ben Pfaff has shown how to fix the code, but I'll offer
another solution:

#include <string.h>
extern inline void copy(void *pSource, void *pDest,
unsigned int dLength)
{
memcpy (pDest, pSource, dLength); /* note arg swap */
}

If you're using a free-standing rather than a hosted
implementation, it's possible that <string.h> and memcpy()
are not provided, but take a look anyhow: If they're present,
they'll likely be speedier than anything written in plain C.
Also, memcpy() will behave unpredictably if the source and
destination areas overlap; you could use memmove() to get
predictable behavior, but that behavior might not be precisely
what you get from the original. You need to study the "contract"
of the copy() function to see if it's a candidate for replacement.
 
K

Keith Thompson

Roman Mashak said:
I'm porting code, previously compiled by IAR compiler, for ARM-gcc compiler.
This snippet results in error, posted in subject:

/*
* copies a structure in a buffer
* pSource Data to copy
* pDest Buffer in which to copy the data
*/
extern inline void copy(void *pSource, void *pDest, unsigned int dLength)
{
unsigned int dI;

for (dI = 0; dI < dLength; dI++) {

*((char *) pDest) = *((char *) pSource);
((char *) pDest)++; /* error */
((char *) pSource)++; /* error */
}
}

As I understand, casting ends up with 'rvalue', and '++' or any other
operations can't be applied to rvalue. So, what is the proper solution here?
[...]

Another possibility is to change the two "++"s to:

pDest = (char*)pDest + 1;
pSource = (char*)pSource + 1;

The void* values are explicitly converted to char* so you can
increment them, then the char* result is implicitly converted back to
void* by the assignment.
 
F

Flash Gordon

Eric Sosman wrote, On 24/12/07 05:17:
Ben Pfaff has shown how to fix the code, but I'll offer
another solution:

#include <string.h>
extern inline void copy(void *pSource, void *pDest,
unsigned int dLength)
{
memcpy (pDest, pSource, dLength); /* note arg swap */
}

Unless you explicitly need the function version I would use a macro instead.
If you're using a free-standing rather than a hosted
implementation, it's possible that <string.h> and memcpy()
are not provided, but take a look anyhow: If they're present,

At least some free-standing implementations provide memcpy (and as much
of the rest of the standard library as they sensibly can).
they'll likely be speedier than anything written in plain C.
Also, memcpy() will behave unpredictably if the source and
destination areas overlap; you could use memmove() to get
predictable behavior, but that behavior might not be precisely
what you get from the original. You need to study the "contract"
of the copy() function to see if it's a candidate for replacement.

Indeed. Personally I would want to change the code that calls copy to
call memmove or memcpy as appropriate. Then there is one less function
for the next maintainer to learn.
 
R

Roman Mashak

Hello,

I'm porting code, previously compiled by IAR compiler, for ARM-gcc compiler.
This snippet results in error, posted in subject:

/*
* copies a structure in a buffer
* pSource Data to copy
* pDest Buffer in which to copy the data
*/
extern inline void copy(void *pSource, void *pDest, unsigned int dLength)
{
unsigned int dI;

for (dI = 0; dI < dLength; dI++) {

*((char *) pDest) = *((char *) pSource);
((char *) pDest)++; /* error */
((char *) pSource)++; /* error */
}
}

As I understand, casting ends up with 'rvalue', and '++' or any other
operations can't be applied to rvalue. So, what is the proper solution here?
I'm unable to find a way :(

Thanks.

With best regards, Roman Mashak. E-mail: (e-mail address removed)
 
A

Ahmed Samieh

Hello,

I'm porting code, previously compiled by IAR compiler, for ARM-gcc compiler.
This snippet results in error, posted in subject:

/*
* copies a structure in a buffer
* pSource Data to copy
* pDest   Buffer in which to copy the data
*/
extern inline void copy(void *pSource, void *pDest, unsigned int dLength)
{
    unsigned int dI;

    for (dI = 0; dI < dLength; dI++) {

        *((char *) pDest) = *((char *) pSource);
        ((char *) pDest)++;    /* error */
        ((char *) pSource)++;    /* error */
    }

}

As I understand, casting ends up with 'rvalue', and '++' or any other
operations can't be applied to rvalue. So, what is the proper solution here?
I'm unable to find a way :(

Thanks.

With best regards, Roman Mashak.  E-mail: (e-mail address removed)

void* mcpy(void *dst, void *src, size_t n)
{
size_t i;
char* ldst = (char*)dst;
char* lsrc = (char*)src;
for (i = 0; i < n; ++i)
{
*ldst++ = *lsrc++;
}
return dst;
}
 
R

Roman Mashak

Hello, Eric!
You wrote on Mon, 24 Dec 2007 00:17:21 -0500:

[skip]
ES> Ben Pfaff has shown how to fix the code, but I'll offer
ES> another solution:

ES> #include <string.h>
ES> extern inline void copy(void *pSource, void *pDest,
ES> unsigned int dLength)
ES> {
ES> memcpy (pDest, pSource, dLength); /* note arg swap */
ES> }
[skip]

Thanks a lot!

With best regards, Roman Mashak. E-mail: (e-mail address removed)
 
C

CBFalconer

Roman said:
I'm porting code, previously compiled by IAR compiler, for ARM-gcc
compiler. This snippet results in error, posted in subject:

/*
* copies a structure in a buffer
* pSource Data to copy
* pDest Buffer in which to copy the data
*/
extern inline void copy(void *pSource, void *pDest, unsigned int dLength) {
unsigned int dI;

for (dI = 0; dI < dLength; dI++) {
*((char *) pDest) = *((char *) pSource);
((char *) pDest)++; /* error */
((char *) pSource)++; /* error */
}
}

As I understand, casting ends up with 'rvalue', and '++' or any
other operations can't be applied to rvalue. So, what is the
proper solution here? I'm unable to find a way :(

/* copies a structure in a buffer. */
extern inline void copy(void *psor, void *pdst, size_t lgh) {
char *cs = psor, cd = pdst;

while (lgh--) *cd++ = *cs++;
} /* untested */

Notice the absence of casts, which are usually errors. Also note
the change in the type of the lgh parameter. The above should drop
in wherever you were calling the old version. Any reasonable
compiler will absorb the extra data items.
 
J

Joe Wright

Roman said:
Hello,

I'm porting code, previously compiled by IAR compiler, for ARM-gcc compiler.
This snippet results in error, posted in subject:

/*
* copies a structure in a buffer
* pSource Data to copy
* pDest Buffer in which to copy the data
*/
extern inline void copy(void *pSource, void *pDest, unsigned int dLength)
{
unsigned int dI;

for (dI = 0; dI < dLength; dI++) {

*((char *) pDest) = *((char *) pSource);
((char *) pDest)++; /* error */
((char *) pSource)++; /* error */
}
}

As I understand, casting ends up with 'rvalue', and '++' or any other
operations can't be applied to rvalue. So, what is the proper solution here?
I'm unable to find a way :(

Thanks.

With best regards, Roman Mashak. E-mail: (e-mail address removed)
Too complicated. First, if copy() would use pSourse and pDest as char*
it should declare them such. :

void copy(char *pSource, char *pDest, unsigned dLength)

Even if you call it with void* the compiler will do the conversions to
char* for you.
 
K

Keith Thompson

Joe Wright said:
Roman said:
I'm porting code, previously compiled by IAR compiler, for ARM-gcc
compiler. This snippet results in error, posted in subject:

/*
* copies a structure in a buffer
* pSource Data to copy
* pDest Buffer in which to copy the data
*/
extern inline void copy(void *pSource, void *pDest, unsigned int dLength)
[...]
Too complicated. First, if copy() would use pSourse and pDest as char*
it should declare them such. :

void copy(char *pSource, char *pDest, unsigned dLength)

Even if you call it with void* the compiler will do the conversions to
char* for you.

I disagree. This kind of thing is exactly what void* is for (see the
standard memcpy() and memmove() functions, for example). If the
parameters are declared as char* (why not unsigned char*?), the
function can't be used with, say, int* arguments without a cast. Any
required explicit conversions should be done inside the function, not
imposed on the user.

Of course, just using memcpy() or memmove() directly is probably
better than re-implementing it.
 

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,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top