2014-04-14 1 views
4

그 당시에 gcc에서 완벽하게 빌드 된 1998 빈티지 C 코드 (~ 50 개 주요 프로그램) ~ 16k 라인을 가지고 있지만 이제 과제의 왼쪽 피연산자로 필요한 많은 "lvalue"가 실패합니다 "첫 번째 루틴의 오류"stutter.c ". 나는 C 프로그래머가 문제를 발견하기에 충분하지 않고 내 문제 (이 오히려 일반적인 오류 메시지와 함께)에 대한 인터넷상의 답변을 검색하는 것처럼 보이지 않는다. 제 (빈티지)로부터1998 년 빈티지 C 코드가 gcc로 컴파일되지 못함

메이크

컴파일 행 :

GCC -03 - 벽 -D__dest_os = -I UNIX/USR/X11 -DPLOTX11 -c -o 더듬 포함/여기서

은 구체적인있다 .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) 

더 많은 코드 내역을 사용할 필요합니다. 이 오류를 설명하는 몇 가지 명백한 deprecated 기능이 있습니까?

저는 Fortran 프로그래머로서의 오랜 경험을 가지고 있지만 C 언어를 완전히 배우기 전에 은퇴했습니다. http://gcc.gnu.org/bugs/에 기존 코드에 대한 유용한 정보를 찾지 못했습니다. 나는 내 현재 프로젝트를 위해 리눅스에서 이러한 루틴을 사용하기 전에 C, C++ 및 gcc 교육을 완료해야하는 번거 로움을 덜어 줄 수있는 도움을 주시면 감사하겠습니다. 감사합니다!

+0

@dyp, 'free_list'의 유형을 모른 채 알기가 어렵습니다 ... @sambledsoe, 더 유익한 오류 메시지가 나올 수 있으므로 gcc 대신 clang으로 컴파일 해 볼 수 있습니까? –

+0

C에서'(some_variable) = 123'이라고 말하는 것은 과거에 합법적 이었습니까? 그게 당신이 여기서하는 일이기 때문이죠. –

+3

@EricLippert 아직 법적으로 ... –

답변

11

gcc는 더 이상 캐스트에 지정할 수 없습니다.

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

는 더 이상 법적 없습니다. rhs와 일치하도록 lh를 캐스팅하는 대신 lh와 일치하도록 rh를 캐스팅합니다. 이를 해결하는 한 가지 방법은 왼쪽 값의 주소를 가져 와서 포인터로 캐스팅 한 다음 해당 포인터를 역 참조하는 것이므로 할당은 캐스트 대신 역 참조입니다.

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

그것은 아주 고통이어야한다, 그래서 이것은, 매크로를 업데이트하여 처리 할 수 ​​있습니다 ...

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

등 ...

이 매크로는 lvalue 또는 rvalue 중 하나로 사용할 수 있습니다.

+0

clang은 다음 오류를 발생시킵니다. "오류 : 캐스트에 대한 할당이 잘못되었습니다. lvalue 캐스트가 지원되지 않습니다." –

+0

@Maxime, 예, 그 오류 메시지는 gcc의 "lvalue가 할당의 왼쪽 피연산자로 필요합니다"보다 유익합니다. – pat

+0

필자는 [this extension]이라고 생각합니다. (http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC69) 문서는 2001 년이지만 (오래된 것을 찾지 못했습니다). – dyp

1

주소를 가져오고, 포인터를 캐스팅하고 참조를 취소하는 것 외에도 "no_strict_aliasing"옵션을 사용해야 할 수도 있습니다. C99은 최적화를 용이하게하기 위해 C의 시스템 상태 모델을 unsigned char[]의 무리로 무효화하기 위해 몇 가지 규칙을 추가했습니다. 이것들 중 가장 불명예스러운 것은 Strict Aliasing Rule입니다.포인터를 "이 포인터가 가리키는 포인터를 X로 해석"하는 방법으로 포인터를 생성하는 코드는 컴파일 할 수 있지만 한 유형을 사용하여 포인터에 쓰고 다른 포인터를 사용하여 읽으면 일반적으로 정의되지 않은 동작이 발생하며 일부 컴파일러는 다음과 같이 해석합니다. 시간과 인과의 법칙에 구속받지 않고 오히려 이상하고 기괴한 방식으로 행동하는 면허.

관련 문제