指针的增量错误中无效的左值

问题描述 投票:1回答:1

将GCC版本3.0更改为4.1之后,我在增量错误中获得了无效的左值

#include <vscreen.h>
#include "vscreen_internal.h"

extern UDINT colPalette[256];

void  memset_f(void *p,USINT value, UDINT len)
{
    register    UDINT longValue = colPalette[value];

    while(len)
    {
        if ( ((UDINT)p&3) == 0 )   /* even address*/
        {
            if (len > 32) /*and more than 32 bytes to fill */
            {
                *((UDINT*)p)++ = longValue;        /* lvalue in increment error*/
                *((UDINT*)p)++ = longValue;        /* lvalue in increment error*/
                *((UDINT*)p)++ = longValue;        /* lvalue in increment error*/
                *((UDINT*)p)++ = longValue;        /* lvalue in increment error*/
                *((UDINT*)p)++ = longValue;        /* lvalue in increment error*/
                *((UDINT*)p)++ = longValue;        /* lvalue in increment error*/
                *((UDINT*)p)++ = longValue;        /* lvalue in increment error*/
                *((UDINT*)p)++ = longValue;        /* lvalue in increment error*/
                len-=32;
                continue;
            }
        }   
        *(USINT*)p++ = (USINT)longValue;         /* lvalue in increment error*/
         len--;
    }
}

#endif
c ansi
1个回答
0
投票

强制转换的结果不是“左值”,因此您不能递增该值。从时间的曙光开始,C就一直是这样,所以您以前的代码一定是依赖于某些可疑的非标准扩展。如何在临时指针(如uint32_t*)中使用正确的类型,而只需执行*ptr++ = ...呢?

总体而言,此代码的格式非常糟糕,需要从头开始进行重写,然后进行仔细的检查和分解。我不太确定目的,以某种方式优化到32个字节的块?因为这样会使缓存更快乐?我不认为该代码是如此有效(不再有效)。

您需要抛弃自制的整数类型,摆脱不必要的复杂*((UDINT*)p)++,摆脱石器时代register,将if(this) if(that) { ...continue; } else替换为if(that && that) {} else,依此类推。手动展开循环是相当老的东西,如今,它通常是过早的优化。

[同样值得注意的是,*((UDINT*)p)当然是严格的别名冲突,因此您必须使用专用的编译器选项(例如-fno-strict-aliasing)进行编译。我希望在源代码中对此进行评论,以证明程序员认为了这一点。

© www.soinside.com 2019 - 2024. All rights reserved.