c - 1998 年的老式 C 代码现在无法在 gcc 下编译

标签 c gcc legacy-code

我有大约 16k 行 1998 年的老式 C 代码(大约 50 个主程序),当时在 gcc 下完美构建,但现在失败了,第一个例程中出现许多“左值需要作为赋值的左操作数”错误,“口吃。 C”。我不是一个足够的 C 程序员来找到问题并且似乎无法在互联网上搜索特定于我的问题的答案(带有这个相当通用的错误消息)。

具体情况如下:

来自(老式)Makefile 的编译行:

gcc -O3 -Wall -D__dest_os=unix -I/usr/X11/include -DPLOTX11 -c -o stutter.o ../src/stutter.c

失败语句示例:

    cell_car(cell) = free_list;
    cell_type(cell) = type;
    cell_name(atom) = strdup(name);
    cell_cdr(list) = binding_list;
    cell_cdr(cell_car(current)) = b;

...(以及许多类似的)

前面是:

    typedef enum CELL_ENUM {
      CELL_LAMBDA, CELL_SFUNC, CELL_VFUNC, CELL_LIST, CELL_ATOM
    } CELL_TYPE;

    typedef struct CELL_STRUCT {
    void *car, *cdr;
    unsigned type : 7;
    unsigned mark : 1;
    char empty[3];
    } CELL;

和:

    #define cell_car(c)      ((CELL *)(c)->car)
    #define cell_cdr(c)      ((CELL *)(c)->cdr)        
    #define cell_name(c)     ((char *)(c)->car)
    #define cell_func(c)     ((CELL *(*)())(c)->car)
    #define cell_type(c)     ((CELL_TYPE)(c)->type)
    #define cell_mark(c)     ((c)->mark)

如果需要,可提供更多代码细节。这里是否有一些明显的弃用功能可以解释此错误??

作为一名科学的 Fortran 程序员,我有多年的经验,但在学习足够多的 C 以完全完成转换之前就退休了。在 http://gcc.gnu.org/bugs/ 上未发现任何有关遗留代码的有用信息.在我为当前项目在 linux 下运行这些例程之前,如果有任何帮助可以让我不必完成我的 C、C++ 和 gcc 教育,我将不胜感激。非常感谢!

最佳答案

gcc 不再允许您分配给类型转换。

((CELL *)(cell)->car) = free_list;

不再合法。与其转换 lhs 以匹配 rhs,不如转换 rhs 以匹配 lhs。解决此问题的一种方法是获取左值的地址,将其转换为指针,然后取消引用该指针,因此赋值是指向指针取消引用而不是强制转换。

*((CELL **)&(cell)->car) = free_list;

这可以通过更新宏来处理,所以应该很轻松...

#define cell_car(c)      (*((CELL **)&(c)->car))

等...

此宏可以用作左值或右值。

关于c - 1998 年的老式 C 代码现在无法在 gcc 下编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23069389/

相关文章:

html - 尝试将 margin-left 添加到输入字段

c - 修改几个GTK按钮

c - MPI 收集多个 vector

ios - 结构填充编译标志

c - 在 C11 中使用 strdup

java - 遗留字符编码

Python:旧式类的 __setattr__?

c - 为什么 GCC 会根据常量的值生成不同的乘法操作码?

c - srand 函数是否适用于多个翻译单元?

c - 这些 LAPACK 计划有何不同之处?一个编译,另一个不编译