ISO C90 prohíbe declaraciones y códigos mixtos en C

82

Declaro una variable de esta manera:

int i = 0;

Recibo la advertencia:

ISO C90 prohíbe declaraciones y códigos mixtos

¿Cómo puedo arreglarlo?

Peter Mortensen
fuente
2
Suena como GCC -pedantico -std=c89, en cuyo caso puede compilar -std=gnu99si lo desea.
Dietrich Epp
3
Si está usando gcc, puede especificar usar C99 que permite declaraciones y código (bandera -std=c99) mixtos .
hmjd
11
Una opción sería dejar de compilar a un estándar de 22 años para el que incluso se reemplazó el reemplazo.
Stephen Canon
4
@StephenCanon, dígaselo a Microsoft. :)
hmjd
2
@hmjd: Microsoft no tiene interés en enviar un compilador de C; eso probablemente no cambiará. Afortunadamente, hay una serie de compiladores perfectamente buenos que apuntan a la plataforma suministrada por otros proveedores.
Stephen Canon

Respuestas:

124

Creo que debería mover la declaración de variable a la parte superior del bloque. Es decir

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

a

{
    int i = 0;
    foo();
    bar();
}
Johan Kotlinski
fuente
5
... o abra un contexto nuevo:{foo(); {int i=0; bar();}}
alk
3
@alk s / context / block Eso es lo que se llama en el estándar C.
Jens
@Johan Kotlinski Pero, ¿por qué importa esto?
ocean800
1
@ ocean800 La especificación C90 decía que no se pueden tener declaraciones después de no declaraciones en el mismo bloque.
MM
37

Hasta el estándar C99, todas las declaraciones tenían que ir antes de cualquier declaración en un bloque:

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

  // code

  if (c)
  {
    int m, n;

    // more code
  }
  // etc.
}

C99 permitió mezclar declaraciones y sentencias (como C ++). Muchos compiladores todavía utilizan C89 de forma predeterminada, y algunos compiladores (como el de Microsoft) no admiten C99 en absoluto .

Por lo tanto, deberá hacer lo siguiente:

  1. Determine si su compilador admite C99 o posterior; si es así, configúrelo para que compile C99 en lugar de C89;

  2. Si su compilador no es compatible con C99 o posterior, necesitará encontrar un compilador diferente que lo admita o reescribir su código para que todas las declaraciones vengan antes de cualquier declaración dentro del bloque.

John Bode
fuente
11

Simplemente use un compilador (o proporcione los argumentos que necesita) de modo que compile para una versión más reciente del estándar C, C99 o C11. Por ejemplo, para la familia de compiladores GCC que sería -std=c99.

Jens Gustedt
fuente
6
Esta respuesta está incompleta en el mejor de los casos. Soluciona el problema pero no explica qué lo causó. Esta respuesta excluye situaciones en las que no es posible un compilador más nuevo (varias razones posibles ...) o entornos de compilación donde no es posible cambiar las opciones al compilador como este. Un voto en contra porque no puedo estar de acuerdo con que esta sea la respuesta "real".
Andrew Falanga
1
En algunos casos -std=gnu89se utiliza al compilar módulos del kernel de Linux.
cbix
4

Asegúrese de que la variable esté en la parte superior del bloque y, en caso de que la compile -ansi-pedantic, asegúrese de que se vea así:

function() {
    int i;
    i = 0;

    someCode();
}
Ron Nuni
fuente
Aún puede inicializar la variable, simplemente no puede colocar el código antes de declararlo.
SS Anne
2

Para diagnosticar lo que realmente desencadena el error, primero intentaría eliminar = 0

  • Si se dispara el error, lo más probable es que la declaración vaya después del código.

  • Si no hay error, entonces puede estar relacionado con indicadores de compilación / cumplimiento del estándar C O ... algo más.

En cualquier caso, declare la variable al comienzo del ámbito actual. Luego puede inicializarlo por separado. De hecho, si esta variable merece su propio alcance, delimite su definición en {}.

Si el PO pudiera aclarar el contexto, se seguiría una respuesta más dirigida.

vmsnomad
fuente
1

-Wdeclaration-after-statement ejemplo mínimo reproducible

C Principal

#!/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

Dar advertencia:

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

No advierta:

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

La advertencia:

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

Probado en Ubuntu 16.04, GCC 6.4.0.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente