无法理解 C 源代码,它不能在 GCC 中编译,但在 Visual C++ 中
Posted
技术标签:
【中文标题】无法理解 C 源代码,它不能在 GCC 中编译,但在 Visual C++ 中【英文标题】:Cannot understand C source and it does not compile in GCC, but in Visual C++ 【发布时间】:2011-01-31 11:04:15 【问题描述】:在 GCC 中出现以下错误:
aes.c:在函数‘copy_block’中: 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 机器上。
提前感谢您的帮助。
【问题讨论】:
我想你想要uint8_t
...
【参考方案1】:
试试这个:
#include <string.h>
static void copy_block( void * d, void *s, uint_8t nn )
memcpy(d, s, (size_t)nn);
那里做的不好。
【讨论】:
那是 C++ ...帖子被标记为“C”,所以我会坚持使用 (size_t)nn 为什么不只是#define copy_block memcpy
让它更有用?
@Chris - 我认为首先编写 'copy_block' 而不是 'memcpy' 是有原因的 - 间接记录日志或其他内容。全局替换甚至比 #define 别名更好。
@sje397 呵呵 :) 但是您显然还需要将 #include 应该这样做:
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;
它也更具可读性。
【讨论】:
强制转换在 C 中是不必要且非惯用的 改用此代码!像在原始帖子中那样编写完全混淆的代码应该被定为犯罪!【参考方案3】:这是一些看起来很毛茸茸的代码。看起来 *(pointer)++ 子表达式的优先级规则存在问题。 (Visual C++ 接受它介于奇迹和错误之间)它似乎只是一个(可怕的)memcpy 重新实现,所以我建议你使用标准版本:
memcpy(d, s, nn);
我建议在 Visual C++ 中进行快速特性测试,以确保代码的两个版本实际上执行相同的操作(正如它们看起来那样)。您可能在此处依赖编译器中的一些古怪的边缘情况。
【讨论】:
【参考方案4】:问题是强制转换返回右值,但您正试图对强制转换返回的指针进行自动增量。试试这个:
uint8_t *da = d, *sa = s;
while(nn--) *da++ = *sa++;
另外两点:
nn
应该比 uint8_t
大很多,应该是 size_t
。
进行该更改后,此函数被命名为 memcpy
,并且可以在您的标准库中找到(可能更有效)(我相信在 string.h
中)。
【讨论】:
@Christoph - 一点也不。现在看起来不像我在 iPhone 上写的了。 :P【参考方案5】:你可能搞砸了括号的位置。 您想增加指针,而不是取消引用的值。
static void copy_block( void * d, void *s, uint_8t nn )
while( nn-- )
*((uint_8t*)d++) = *((uint_8t*)s++);
作为额外提示,使用 memcpy ... 更快!
【讨论】:
后缀++
比一元 *
具有更高的优先级,除非我错了。
不,后缀++
的优先级更高,这意味着它比*
绑定得更紧密,这意味着您不需要为任何内容加上括号。代码仍然不起作用,因为您在右值上使用了自增运算符,这就是错误所述。
对于本应是一种语言的基本特征的东西争论不休。也许最好不要以容易被误读的方式编写代码。
K&R 和 70 年代的任何编程人员一样,编写代码是因为他们想节省源代码文件占用的硬盘空间。除非您的 Terrabyte HD 上更多字节的源代码是您的主要关注点,否则不要编写混淆代码。使用下面 detunized 发布的版本,它应该在性能方面完全等效。
@246tNt:您缺少-pedantic
标志:您的代码使用了非标准编译器扩展...【参考方案6】:
应该是:
static void copy_block( void * d, void *s, uint_8t nn )
while( nn-- )
(*((uint_8t*)d))++ = (*((uint_8t*)s))++;
【讨论】:
与原始代码相同的问题......没有工作希望。我很惊讶 visual-c++ 编译它。 ..以上是关于无法理解 C 源代码,它不能在 GCC 中编译,但在 Visual C++ 中的主要内容,如果未能解决你的问题,请参考以下文章