ISO C90禁止在C语言中混合声明和代码。

110

我用以下方式声明了一个变量:

int i = 0;

我收到了警告:

ISO C90 禁止混合声明和代码

我该如何修复它?


3
如果你觉得这听起来像 GCC 的 -pedantic 或者 -std=c89,那么你可以使用 -std=gnu99 进行编译,如果你愿意的话。 - Dietrich Epp
3
如果你使用的是gcc编译器,你可以加上-std=c99这个参数,这样就可以使用C99标准。C99允许在代码中夹杂声明语句和其他语句。 - hmjd
14
一种选择是停止编译到一个已经有22年历史且其替代品也已经被替换的标准上。 - Stephen Canon
6
@StephenCanon,请转达给微软。 :) - hmjd
2
@hmjd:微软没有兴趣发布C编译器;这种情况可能不会改变。幸运的是,有许多其他供应商提供的针对该平台的完全良好的编译器。 - Stephen Canon
显示剩余3条评论
7个回答

170

我认为你应该将变量声明移到代码块顶部,即:

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

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

5
...或打开一个新的上下文:{foo(); {int i=0; bar();}} (注:翻译中保留了代码语法和标点符号,以确保表达准确无误。) - alk
3
@alk s/context/block 这是在C标准中所称的。 - Jens
1
@Johan Kotlinski 但这有什么关系呢? - ocean800
3
C90规范规定,在同一代码块中不能在非声明语句后面再出现声明语句。 - M.M

47

在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或更高版本; 如果是,请配置它以编译C99而不是C89;

  2. 如果您的编译器不支持C99或更高版本,则需要找到另一个 支持 它的编译器,或者重写代码,以使块内的所有声明都在任何语句之前。


11

只需使用编译器(或为其提供所需参数),使其编译更高版本的C标准,如C99或C11。例如,对于GCC编译器系列,应使用-std=c99参数。


6
这个答案充其量只是不完整的。它确实解决了问题,但没有解释是什么导致了这个问题。此答案排除了一些情况,比如无法使用更新的编译器(有很多可能的原因...),或者在构建环境中切换编译器选项并不可行等。我不能同意这是“真正的”答案,因此会给出一个反对票。 - Andrew Falanga
1
在编译Linux内核模块时,有些情况下会使用"-std=gnu89"。 - cbix

6

确保变量位于块的顶部,并且在使用-ansi-pedantic编译时,确保它看起来像这样:

function() {
    int i;
    i = 0;

    someCode();
}

1
你仍然可以初始化变量,只是在声明之前不能放置代码。 - S.S. 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://dev59.com/KWUq5IYBdhLWcg3wKtRL#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上进行了测试。


1

确保在块中的任何语句之前声明变量。

例如:

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

我相信这会有所帮助:
https://www.configrouter.com/iso-c90-forbids-mixed-declarations-and-code-in-c-30621/
ISO C90禁止在C语言中混合声明和代码。

其他答案已经有这个信息了。 - user16217248

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接