2016-12-07 6 views
1

이 내 코드 (C 오류) 상수 값이 있어야합니다

int main (void) { 

    struct state 
    { 
     int output; 
     int time; 
     const struct state *next[4]; 
    }; 

    typedef const struct state state_t; 

    # define wait1noclick &fsm[0] 
    # define fast2 &fsm[1] 
    # define wait2noclick &fsm[2] 
    # define fast1 &fsm[3] 
    # define wait1click &fsm[4] 
    # define wait1 &fsm[5] 
    # define wait2click &fsm[6] 
    # define wait2 &fsm[7] 

    state_t fsm[8] = 
    { 
     {0xC, 600, {wait1noclick, fast2, wait1click, fast2}}, 
     {0x1, 150, {fast2, wait2noclick, fast2, wait2noclick}}, 
     {0x3, 600, {wait2noclick, fast1, wait2click, fast1}}, 
     {0x4, 150, {fast1, wait1noclick, fast1, wait1noclick}}, 
     {0x8, 200, {wait1click, wait1, wait1click, wait1}}, 
     {0x5, 200, {wait1, fast2, wait1, fast2}}, 
     {0x2, 200, {wait2click, wait2, wait2click, wait2}}, 
     {0xA, 200, {wait2, fast1, wait2, fast1}} 
    }; 
} 

문제없이 컴파일 suposed되어 있지만 각 "FSM에서이 오류 메시지가 모든 시간, 4 시간을 얻고있다 "행 :

error: #28: expression must have a constant value 

내가 뭘 잘못하고 있는지 알아?

+3

주소가 일정해야하므로 '메인'외부에서해야합니다. 정적 저장소 클래스가 있어야합니다. 'main' 내부에 타입을 정의하는 것은 그 자체로 나쁜 생각입니다. –

+1

은'main' 함수 밖에서 잘 작동합니다. –

+0

고마워요! 그것으로 문제가 해결됩니다. 원한다면 의견 대신 답변을 게시하여 승인 된 답변으로 표시 할 수 있습니다. – Sergio

답변

2

현대 C 언어의 관점에서 본다면 아무 문제가 없습니다.

그러나 아주 오래된 C89/90 컴파일러를 사용하는 경우 모든 집계 초기화 프로그램이 상수 표현으로 구성되어야합니다. 이렇게하면 이니셜 라이저에서 로컬 객체의 주소를 사용할 수 없게됩니다. 이러한 주소는 상수가 아니기 때문입니다.

이 제한은 C99에서 해제되었습니다. 자동 개체의 집계 이니셜 라이저는 더 이상 상수 식에만 제한되지 않습니다.

그러나 내가 아는 모든 C89/90 컴파일러는 제한 사항을 무시하고 시대의 시작부터 현대적 행동을 지원했습니다. 컴파일러가 의도적으로 C89/90 규칙의 아주 페 데 틱한 실행을 위해 구성되어있을 수 있습니까?

+0

안녕하세요, 답변 주셔서 감사합니다. 나는 영어가 제 주요 언어가 아니기 때문에 당신의 설명을 이해하기가 약간 어렵습니다. 아마도 지식이 필요하지 않을 수도 있습니다. 하지만 문제는 내 컴파일러는 오래된 컴파일러이며 상수를 주 외부에서 초기화해야한다는 것입니다. 관심이 있으시면 Keil uVision4를 사용하고 있습니다. 설명해 주셔서 다시 한 번 감사드립니다! – Sergio

+0

@Sergio : 컴파일러가 반드시 "오래되었습니다"것은 아닙니다. 그것은 1989 년부터 "고전적인"C 언어 표준의 규칙을 시행적으로 집행하도록 구성 될 수 있습니다. 그것이 "자연스러운"구성이든 - 나는 정말로 모른다. – AnT