Cannot understand C source and it does not compile in GCC, but in Visual C++
In GCC I got the following error:
aes.c: In function 开发者_如何学运维‘copy_block’:
aes.c:278: error: lvalue required as increment operand aes.c:278: error: lvalue required as increment operand
This is the piece of code:
static void copy_block( void * d, void *s, uint_8t nn )
{
while( nn-- )
*((uint_8t*)d)++ = *((uint_8t*)s)++;
}
I tried to change it to a compileable version, but unfortunately for me as a Java programmer, it's not clear what is really happening here.
Maybe someone has an idea how I can change the source that it is compileable in GCC or someone has an idea what is happening here in detail. For me it seems wierd with the dereferencing of the left hand value, but somehow it seems to work perfectly in Visual C++.
This is a small legacy program, which I have to port to a Linux machine.
thank you for your help in advance.
Try this:
#include <string.h>
static void copy_block( void * d, void *s, uint_8t nn ) {
memcpy(d, s, (size_t)nn);
}
What's being done there isn't good.
This should do it:
static void copy_block(void *d, void *s, uint_8t nn)
{
uint_8t *ud = (uint_8t *)d;
uint_8t *us = (uint_8t *)s;
while (nn--)
{
*ud = *us;
++ud;
++us;
}
}
It's also much more readable.
This is some seriously hairy looking code. Looks like there's an issue with precedence rules on the *(pointer)++ subexpressions. (that Visual C++ accepts it is somewhere between miracle and bug) It seems to be just a (terrible) memcpy reimplementation, so I suggest you use the standard version:
memcpy(d, s, nn);
I suggest doing a quick characterisation test in Visual C++ to make sure the two versions of the code do in fact do the same thing (as they appear to). You might be relying on some quirky edge case in the compiler here.
The problem is that casts return rvalues, but you're trying to do an autoincrement on the pointer returned by a cast. Try this:
uint8_t *da = d, *sa = s;
while(nn--) *da++ = *sa++;
Two other notes:
nn
should probably be a good deal larger thanuint8_t
and should probably besize_t
.- With that change, this function is named
memcpy
and is found (probably more efficiently) in your standard library (instring.h
I believe).
You probably screwed up the parenthesis position. You want to increment the pointer, not the dereferenced value.
static void copy_block( void * d, void *s, uint_8t nn )
{
while( nn-- )
*((uint_8t*)d++) = *((uint_8t*)s++);
}
As a bonus tip, use memcpy ... much faster !
It's a duplicate of Why isn't the result of this cast an lvalue?
Basically casts are not l-value. It works with some compilers though. Not only old GCC, quite recent Tasking also compiled "properly" and the code worked.
Should be:
static void copy_block( void * d, void *s, uint_8t nn )
{
while( nn-- )
(*((uint_8t*)d))++ = (*((uint_8t*)s))++;
}
精彩评论