Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

1998 vintage C code now fails to compile under gcc

Tags:

c

gcc

legacy-code

I have ~16k lines of 1998 vintage C code (~50 main progs) which built flawlessly under gcc at that time but now fails with many "lvalue required as left operand of assignment" errors in the first routine, "stutter.c". I'm not enough of a C programmer to find the problem and can't seem to search out an answer on the internet specific to my problem (with this rather generic error message).

Here are the specifics:

Compile line from the (vintage) Makefile:

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

Failing statement examples:

    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;

... (and many similar)

preceded by:

    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;

and:

    #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)

More code particulars available if needed. Is there some obvious deprecated feature here which explains this error??

I have many years of experience as a scientific Fortran programmer but retired before learning enough of C to completely make the switch. Haven't found anything helpful about legacy code at http://gcc.gnu.org/bugs/. I'd appreciate any help that would save me having to complete my C, C++ and gcc education before I get these routines working under linux for my current project. Thanks much!

like image 212
sambledsoe Avatar asked Apr 14 '14 20:04

sambledsoe


1 Answers

gcc is no longer allowing you to assign to a cast.

i.e.

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

is no longer legal. Instead of casting the lhs to match the rhs, it would rather you cast the rhs to match the lhs. One way around this is to take the address of the lvalue, cast it as a pointer, and then dereference that pointer, so the assignment is to a pointer dereference instead of a cast.

i.e.

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

This can be handled by updating the macros, so it should be quite painless...

i.e.

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

etc...

This macro can then be used as either an lvalue or an rvalue.

like image 120
pat Avatar answered Oct 20 '22 15:10

pat