ISO C90은 C에서 혼합 된 선언과 코드를 금지합니다.


82

이 방법으로 변수를 선언했습니다.

int i = 0;

경고를받습니다.

ISO C90은 혼합 선언 및 코드를 금지합니다.

어떻게 고칠 수 있습니까?


2
GCC -pedantic또는 처럼 들리며 -std=c89,이 경우 원하는 경우 컴파일 할 수 있습니다 -std=gnu99.
Dietrich Epp

3
gcc를 사용하는 경우 혼합 선언 및 코드 (flag -std=c99) 를 허용하는 C99를 사용하도록 지정할 수 있습니다 .
hmjd

11
한 가지 옵션은 대체품도 교체 된 22 년 된 표준으로 컴파일하는 것을 중지하는 것입니다.
Stephen Canon

4
@StephenCanon, Microsoft에 알려주십시오. :)
hmjd

2
@hmjd : Microsoft는 C 컴파일러를 제공하는 데 관심이 없습니다. 그것은 변하지 않을 것입니다. 다행히도 다른 공급 업체에서 제공하는 플랫폼을 대상으로하는 완벽하게 우수한 컴파일러가 많이 있습니다.
Stephen Canon

답변:


124

변수 선언을 블록 맨 위로 이동해야한다고 생각합니다. 즉

{
    foo();
    int i = 0;
    bar();
}

...에

{
    int i = 0;
    foo();
    bar();
}

5
... 또는 새로운 컨텍스트 열기 :{foo(); {int i=0; bar();}}
alk

3
@alk s / context / block 이것이 C 표준에서 부르는 것입니다.
Jens

@Johan Kotlinski 그런데 이것이 왜 중요할까요?
ocean800

1
@ ocean800 C90 사양에 따르면 동일한 블록에서 비 선언 후에는 선언을 할 수 없습니다.
MM

37

C99 표준까지는 모든 선언이 블록의 모든 문 앞에 와야했습니다.

void foo()
{
  int i, j;
  double k;
  char *c;

  // code

  if (c)
  {
    int m, n;

    // more code
  }
  // etc.
}

C99는 선언과 문을 혼합 할 수 있습니다 (예 : C ++). 많은 컴파일러는 여전히 C89로 기본 설정되어 있으며 일부 컴파일러 (예 : Microsoft)는 C99 를 전혀 지원하지 않습니다 .

따라서 다음을 수행해야합니다.

  1. 컴파일러가 C99 이상을 지원하는지 확인하십시오. 그렇다면 C89 대신 C99를 컴파일하도록 구성하십시오.

  2. 컴파일러 나중에 C99를 지원하지 않거나, 당신도 할 필요가 다른 컴파일러 찾을 것이다 않습니다 를 지원, 또는 모든 선언은 블록 내 모든 문 앞에 와야 있도록 코드를 다시 작성합니다.


11

컴파일러를 사용 (또는 필요한 인수와 함께 제공)하여 최신 버전의 C 표준, C99 또는 C11 용으로 컴파일하십시오. 예를 들어 GCC 컴파일러 제품군의 경우 -std=c99.


6
이 답변은 기껏해야 불완전합니다. 문제를 해결하지만 원인은 설명하지 않습니다. 이 답변은 새로운 컴파일러가 불가능한 상황 (몇 가지 가능한 이유 ...) 또는 이와 같이 옵션을 컴파일러로 전환 할 수없는 환경을 빌드하는 것을 제외합니다. 이것이 "진짜"대답이라는 데 동의 할 수 없기 때문에 반대표입니다.
Andrew Falanga 2015

1
어떤 경우에는 -std=gnu89리눅스 커널 모듈을 컴파일 할 때 사용됩니다.
cbix

4

변수가 블록의 맨 위에 있는지 확인하고로 컴파일하는 경우 다음과 -ansi-pedantic같은지 확인하십시오.

function() {
    int i;
    i = 0;

    someCode();
}

변수를 초기화 할 수는 있지만 선언하기 전에 코드를 배치 할 수 없습니다.
SS Anne

2

실제로 오류를 유발하는 원인을 진단하기 위해 먼저 = 0

  • 오류가 발생하면 선언이 코드 다음에 올 가능성이 큽니다.

  • 오류가 없으면 C 표준 시행 / 컴파일 플래그 또는 다른 것과 관련이있을 수 있습니다.

어쨌든 현재 범위의 시작 부분에 변수를 선언하십시오. 그런 다음 별도로 초기화 할 수 있습니다. 실제로이 변수가 자체 범위를 가질 자격이있는 경우-정의를 {}로 구분하십시오.

OP가 컨텍스트를 명확히 할 수 있다면보다 직접적인 응답이 뒤따를 것입니다.


1

-Wdeclaration-after-statement 재현 가능한 최소한의 예

main.c

#!/usr/bin/env bash

set -eux

cat << EOF > main.c
#include <stdio.h>

int main(void) {
    puts("hello");
    int a = 1;
    printf("%d\n", a);
    return 0;
}
EOF

경고 제공 :

gcc -std=c89 -Wdeclaration-after-statement -Werror main.c
gcc -std=c99 -Wdeclaration-after-statement -Werror main.c
gcc -std=c89 -pedantic -Werror main.c

경고하지 마십시오 :

gcc -std=c89 -pedantic -Wno-declaration-after-statement -Werror main.c
gcc -std=c89 -Wno-declaration-after-statement -Werror main.c
gcc -std=c99 -pedantic -Werror main.c
gcc -std=c89 -Wall -Wextra -Werror main.c
# https://stackoverflow.com/questions/14737104/what-is-the-default-c-mode-for-the-current-gcc-especially-on-ubuntu/53063656#53063656
gcc -pedantic -Werror main.c

경고 :

main.c: In function ‘main’:
main.c:5:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
     int a = 1;
     ^~~

Ubuntu 16.04, GCC 6.4.0에서 테스트되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.