无法理解C源代码,并且它不能在GCC中编译,而只能在Visual C++中编译

qgelzfjb  于 2022-11-13  发布在  其他
关注(0)|答案(7)|浏览(186)

在GCC中,我得到了以下错误:
aes.c:在函数“复制块”中:
aes.c:278:错误:需要左值作为增量操作数
aes.c:278:错误:需要左值作为增量操作数
这是一段代码:

static void copy_block( void * d, void *s, uint_8t nn )
{
    while( nn-- )
        *((uint_8t*)d)++ = *((uint_8t*)s)++;
}

我试图将其更改为可编译的版本,但不幸的是,作为一名Java程序员,我并不清楚这里到底发生了什么。
也许有人知道我如何改变源代码,使其在GCC中是可编译的,或者有人知道这里发生了什么细节。对我来说,它似乎与左手值的取值很奇怪,但不知何故,它似乎在Visual C++中完美地工作。
这是一个小的遗留程序,我必须将其移植到Linux机器上。
预先感谢你帮助。

6gpjuf90

6gpjuf901#

试试看:

#include <string.h>
static void copy_block( void * d, void *s, uint_8t nn ) {
  memcpy(d, s, (size_t)nn);
}

那里做的事情不好。

omtl5h9j

omtl5h9j2#

这应该可以做到:

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;
    }
}

它的可读性也更强。

plicqrtu

plicqrtu3#

这段代码看起来非常复杂。看起来 *(pointer)子表达式的优先级规则有问题。(Visual C接受它是一个介于奇迹和bug之间的问题)它看起来只是一个(糟糕的)memcpy重新实现,所以我建议您使用标准版本:
memcpy(d, s, nn);
我建议在Visual C++中做一个快速的特性测试,以确保这两个版本的代码实际上做了同样的事情(就像它们看起来的那样)。

fivyi3re

fivyi3re4#

问题是强制类型转换返回右值,但是您试图对强制类型转换返回的指针执行自动递增。

uint8_t *da = d, *sa = s;
while(nn--) *da++ = *sa++;

另外两个注意事项:

  • nn应该比uint8_t大得多,并且应该是size_t
  • 经过修改后,这个函数被命名为memcpy,可以在您的标准库中找到(可能更有效)(我相信是在string.h中)。
dfddblmv

dfddblmv5#

您可能弄错了括号的位置。您想要递增指针,而不是解除引用的值。

static void copy_block( void * d, void *s, uint_8t nn )
{
    while( nn-- )
        *((uint_8t*)d++) = *((uint_8t*)s++);
}

作为一个额外的提示,使用memcpy...快得多!

b4wnujal

b4wnujal6#

它是Why isn't the result of this cast an lvalue?的副本
基本上,强制类型转换不是左值的。它可以在一些编译器中使用。不仅是旧的GCC,最近的Tasking也可以正确编译,代码也可以正常工作。

dgsult0t

dgsult0t7#

应道:

static void copy_block( void * d, void *s, uint_8t nn )
{
    while( nn-- )
        (*((uint_8t*)d))++ = (*((uint_8t*)s))++;
}

相关问题