开发者

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 than uint8_t and should probably be size_t.
  • With that change, this function is named memcpy and is found (probably more efficiently) in your standard library (in string.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))++;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜