本帖最后由 liuchang 于 2016-6-15 10:48 编辑
问题见附件,恳请各位指教~~~
[mw_shl_code=c,true]void mymemcpy(void *des, void *src, u32 n)
{
u8 *xdes = des;
u8 *xsrc = src;
while(n--) *xdes++ = *xsrc++;
};[/mw_shl_code][mw_shl_code=c,true]void mymemcpy(void *des, void *src, u32 n)
{ //上面程序是原子的源码,下面这个是我自己写的
while(n--) *(u8 *)des++ = *(u8 *)src++; //小弟不太明白,为什么在源码中需要先申请局部变量,直接操作形参不是更直接,而且代码更加简洁吗?
} //我看网上也有很多源码也是采用原子的这个形式,小弟实在是想不通,恳请原子哥和各位大神指教~~~[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
IAR FOR ARM 6.7 下面这个语句有两个编译错误提示
while(n--) *(u8 *)des++ = *(u8 *)src++;
Error[Pe852]: expression must be a pointer to a complete object type
Error[Pe852]: expression must be a pointer to a complete object type
*(u8 *)des++这里面的 “*” “(u8*)” 和“++”都是相同优先级,自右向左结合,就是说 des先++,然后被强制转换为(u8*)类型,而转化之前的des是void*类型,有的编译器中不能直接进行++操作,就会出现错误expression must be a pointer to a complete object type。
楼主能编译通过,且运行无问题的话,估计是编译器把void* 当做u8*类型处理了。
解决上面的问题可以多加个括号
while(n--) *((u8 *)des)++ = *((u8 *)src)++;
这样确保先把void*类型转换为u8*类型,然后++,可惜遗憾的发现,这样在我的编译环境里还是错误的,报错Error[Pe137]: expression must be a modifiable lvalue,貌似编译器把((u8 *)des)作为常量对待,导致无法进行++操作。可见我的这个编译器并没有那么“灵活”。。。
为了能在我的环境下编译通过,把楼主的两段函数改成这样,void*用u8*类型代替,比较汇编结果
void mymemcpy1(u8 *des, u8 *src, u32 n)
{
u8 *xdes = des;
u8 *xsrc = src;
while(n--) *xdes++ = *xsrc++;
}
void mymemcpy2(u8 *des, u8 *src, u32 n)
{
while(n--) *des++ = *src++;
}
在我的编译器在LOW及更高的优化等级下,两段代码的汇编结果是完全一样的。只有在优化等级为NONE时,第一段代码会多一点点。
所以在下不成熟的猜测:两种形式汇编结果基本一致,但写成第一种形式能更好兼容不同的编译器(正如3楼 @myxiaoniao 所说)。
还有很多疑惑,坐等大神补充指正。
一周热门 更多>