将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就一直是这样,所以您以前的代码一定是依赖于某些可疑的非标准扩展。如何在临时指针(如uint32_t*
)中使用正确的类型,而只需执行*ptr++ = ...
呢?
总体而言,此代码的格式非常糟糕,需要从头开始进行重写,然后进行仔细的检查和分解。我不太确定目的,以某种方式优化到32个字节的块?因为这样会使缓存更快乐?我不认为该代码是如此有效(不再有效)。
您需要抛弃自制的整数类型,摆脱不必要的复杂*((UDINT*)p)++
,摆脱石器时代register
,将if(this) if(that) { ...continue; } else
替换为if(that && that) {} else
,依此类推。手动展开循环是相当老的东西,如今,它通常是过早的优化。
[同样值得注意的是,*((UDINT*)p)
当然是严格的别名冲突,因此您必须使用专用的编译器选项(例如-fno-strict-aliasing
)进行编译。我希望在源代码中对此进行评论,以证明程序员认为了这一点。