108

I declared a variable in this way:

int i = 0;

I get the warning:

ISO C90 forbids mixed declarations and code

How can I fix it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 3
    It sounds like GCC's `-pedantic` or `-std=c89`, in which case you can compile with `-std=gnu99` if you like. – Dietrich Epp Nov 08 '12 at 14:56
  • 3
    If you are using gcc you can specify to use C99 which allows mixed declarations and code (flag `-std=c99`). – hmjd Nov 08 '12 at 14:56
  • 13
    One option would be to stop compiling to a standard that's 22 years old for which even the replacement has been replaced. – Stephen Canon Nov 08 '12 at 14:56
  • 1
    Answering your comment in my answer (now deleted): no, C99 actually introduced intermingled declarations: variable declaration is no longer restricted to file scope or the start of a compound statement (block). I wonder, though, why do you have to use C90-compiler? – raina77ow Nov 08 '12 at 14:56
  • 6
    @StephenCanon, please tell Microsoft that. :) – hmjd Nov 08 '12 at 14:56
  • 2
    @hmjd: Microsoft has no interest in shipping a C compiler; that will likely not change. Fortunately, there are a number of perfectly good compilers targeting the platform supplied by other vendors. – Stephen Canon Nov 08 '12 at 14:57
  • 1
    @StephenCanon: Eight years later: The most recent C standard that GCC has fully implemented is C90. GCC has yet to fully implement C99. GCC's default standard is G90, which is C90 plus a few select features of C99 and a few additional features. – jvriesem Feb 28 '20 at 14:46

7 Answers7

165

I think you should move the variable declaration to top of block. I.e.

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

to

{
    int i = 0;
    foo();
    bar();
}
Johan Kotlinski
  • 25,185
  • 9
  • 78
  • 101
47

Up until the C99 standard, all declarations had to come before any statements in a block:

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

  // code

  if (c)
  {
    int m, n;

    // more code
  }
  // etc.
}

C99 allowed for mixing declarations and statements (like C++). Many compilers still default to C89, and some compilers (such as Microsoft's) don't support C99 at all.

So, you will need to do the following:

  1. Determine if your compiler supports C99 or later; if it does, configure it so that it's compiling C99 instead of C89;

  2. If your compiler doesn't support C99 or later, you will either need to find a different compiler that does support it, or rewrite your code so that all declarations come before any statements within the block.

John Bode
  • 119,563
  • 19
  • 122
  • 198
11

Just use a compiler (or provide it with the arguments it needs) such that it compiles for a more recent version of the C standard, C99 or C11. E.g for the GCC family of compilers that would be -std=c99.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • 6
    This answer is incomplete at best. It does fix the problem but doesn't explain what caused it. This answer excludes situations where a newer compiler isn't possible (several possible reasons ...) or build environments where switching options to the compiler like this isn't possible. A down vote because I can't agree this is the "real" answer. – Andrew Falanga Jul 08 '15 at 18:44
  • 1
    In some cases `-std=gnu89` is used when compiling linux kernel modules. – cbix Mar 13 '17 at 20:36
6

Make sure the variable is on the top part of the block, and in case you compile it with -ansi-pedantic, make sure it looks like this:

function() {
    int i;
    i = 0;

    someCode();
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ron
  • 1,695
  • 1
  • 19
  • 15
2

To diagnose what really triggers the error, I would first try to remove = 0

  • If the error is tripped, then most likely the declaration goes after the code.

  • If no error, then it may be related to a C-standard enforcement/compile flags OR ...something else.

In any case, declare the variable in the beginning of the current scope. You may then initialize it separately. Indeed, if this variable deserves its own scope - delimit its definition in {}.

If the OP could clarify the context, then a more directed response would follow.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
vmsnomad
  • 319
  • 2
  • 7
1

-Wdeclaration-after-statement minimal reproducible example

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

Give warning:

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

Don't give warning:

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

The warning:

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

Tested on Ubuntu 16.04, GCC 6.4.0.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
1

Ensure you made your declarations before any statements in the block. For instance:

{
int i = 0;
printf("a string");/*the code is not a working code*/
}

I believe this should be helpful:

https://www.configrouter.com/iso-c90-forbids-mixed-declarations-and-code-in-c-30621/