ISO C90 verbietet gemischte Deklarationen und Code in C.

82

Ich habe eine Variable folgendermaßen deklariert:

int i = 0;

Ich bekomme die Warnung:

ISO C90 verbietet gemischte Deklarationen und Code

Wie kann ich es reparieren?

Peter Mortensen
quelle
2
Es klingt wie GCCs -pedanticoder -std=c89, in welchem ​​Fall Sie kompilieren können, -std=gnu99wenn Sie möchten.
Dietrich Epp
3
Wenn Sie gcc verwenden, können Sie angeben, dass C99 verwendet werden soll, das gemischte Deklarationen und Code (Flag -std=c99) zulässt .
hmjd
11
Eine Möglichkeit wäre, die Kompilierung auf einen 22 Jahre alten Standard zu beenden, für den sogar der Ersatz ersetzt wurde.
Stephen Canon
4
@ StephenCanon, bitte sagen Sie Microsoft das. :)
hmjd
2
@hmjd: Microsoft hat kein Interesse daran, einen C-Compiler zu liefern. das wird sich wahrscheinlich nicht ändern. Glücklicherweise gibt es eine Reihe perfekter Compiler, die auf die von anderen Anbietern bereitgestellte Plattform abzielen.
Stephen Canon

Antworten:

124

Ich denke, Sie sollten die Variablendeklaration an den Anfang des Blocks verschieben. Dh

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

zu

{
    int i = 0;
    foo();
    bar();
}
Johan Kotlinski
quelle
5
... oder eröffnen Sie einen neuen Kontext:{foo(); {int i=0; bar();}}
Alk
3
@alk s / context / block So heißt es im C-Standard.
Jens
@ Joan Kotlinski Aber warum ist das wichtig?
ocean800
1
@ ocean800 Die C90-Spezifikation besagt, dass Sie keine Deklarationen nach Nichtdeklarationen im selben Block haben können.
MM
37

Bis zum C99-Standard mussten alle Deklarationen vor Aussagen in einem Block stehen:

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

  // code

  if (c)
  {
    int m, n;

    // more code
  }
  // etc.
}

C99 erlaubt das Mischen von Deklarationen und Anweisungen (wie C ++). Viele Compiler verwenden immer noch standardmäßig C89, und einige Compiler (z. B. Microsoft) unterstützen C99 überhaupt nicht .

Sie müssen also Folgendes tun:

  1. Stellen Sie fest, ob Ihr Compiler C99 oder höher unterstützt. Wenn dies der Fall ist, konfigurieren Sie es so, dass C99 anstelle von C89 kompiliert wird.

  2. Wenn Ihr Compiler C99 oder höher nicht unterstützt, müssen Sie entweder einen anderen Compiler finden, der dies unterstützt, oder Ihren Code neu schreiben, sodass alle Deklarationen vor Anweisungen innerhalb des Blocks stehen.

John Bode
quelle
11

Verwenden Sie einfach einen Compiler (oder geben Sie ihm die erforderlichen Argumente), damit er für eine neuere Version des C-Standards C99 oder C11 kompiliert wird. Zum Beispiel für die GCC-Compilerfamilie -std=c99.

Jens Gustedt
quelle
6
Diese Antwort ist bestenfalls unvollständig. Es behebt das Problem, erklärt aber nicht, was es verursacht hat. Diese Antwort schließt Situationen aus, in denen ein neuerer Compiler nicht möglich ist (mehrere mögliche Gründe ...) oder Umgebungen zu erstellen, in denen ein Wechsel der Optionen zum Compiler wie dieser nicht möglich ist. Eine Abwertung, weil ich nicht zustimmen kann, ist die "echte" Antwort.
Andrew Falanga
1
In einigen Fällen -std=gnu89wird beim Kompilieren von Linux-Kernelmodulen verwendet.
cbix
4

Stellen Sie sicher, dass sich die Variable im oberen Teil des Blocks befindet, und stellen Sie beim Kompilieren -ansi-pedanticFolgendes sicher:

function() {
    int i;
    i = 0;

    someCode();
}
Ron Nuni
quelle
Sie können die Variable weiterhin initialisieren. Sie können nur keinen Code platzieren, bevor Sie ihn deklarieren.
SS Anne
2

Um zu diagnostizieren, was den Fehler wirklich auslöst, würde ich zuerst versuchen, ihn zu entfernen = 0

  • Wenn der Fehler ausgelöst wird, folgt die Deklaration höchstwahrscheinlich dem Code.

  • Wenn kein Fehler vorliegt, kann dies mit einem C-Standard für Durchsetzungs- / Kompilierungsflags oder ... etwas anderem zusammenhängen.

In jedem Fall deklarieren Sie die Variable am Anfang des aktuellen Bereichs. Sie können es dann separat initialisieren. Wenn diese Variable ihren eigenen Gültigkeitsbereich verdient, begrenzen Sie ihre Definition in {}.

Wenn das OP den Kontext klären könnte, würde eine gezieltere Antwort folgen.

vmsnomad
quelle
1

-Wdeclaration-after-statement minimal reproduzierbares Beispiel

Haupt 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

Warnung geben:

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

Keine Warnung geben:

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

Die Warnung:

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

Getestet unter Ubuntu 16.04, GCC 6.4.0.

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