ISO C90禁止使用C语言混合声明和代码


82

我以这种方式声明了一个变量:

int i = 0;

我得到警告:

ISO C90禁止混合声明和代码

我该如何解决?


2
听起来像是GCC-pedantic-std=c89,在这种情况下,您可以根据需要进行编译-std=gnu99
Dietrich Epp 2012年

3
如果使用的是gcc,则可以指定使用C99,该C99允许使用混合声明和代码(标志-std=c99)。
hmjd 2012年

11
一种选择是停止编译为22岁的标准,即使是替代品也已被替换。
斯蒂芬·佳能

4
@StephenCanon,请告诉微软。:)
hmjd 2012年

2
@hmjd:Microsoft对交付C编译器没有兴趣;那可能不会改变。幸运的是,有许多针对其他厂商提供的平台的优秀编译器。
斯蒂芬·佳能

Answers:


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)2013年

@Johan Kotlinski但是为什么这很重要?
ocean800 '16

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,和一些编译器(如微软)不支持C99可言

因此,您需要执行以下操作:

  1. 确定您的编译器是否支持C99或更高版本;如果是这样,请对其进行配置,以使其编译为C99而不是C89;

  2. 如果你的编译器不支持C99或更高版本,你要么需要找到一个不同的编译器支持它,或者重写代码,使所有声明的块内的所有语句之前。


11

只需使用编译器(或向其提供所需的参数),使其可以针对C标准的最新版本C99或C11进行编译。例如对于GCC系列的编译器-std=c99


6
这个答案充其量是不完整的。它确实解决了问题,但没有解释导致问题的原因。该答案排除了无法使用较新的编译器的情况(有多种可能的原因...),或者无法构建无法将选项切换至编译器的环境。投反对票,因为我不同意这是“真正的”答案。
安德鲁·法兰加

1
在某些情况下-std=gnu89,用于编译Linux内核模块。
cbix

4

确保变量位于块的顶部,如果使用进行编译-ansi-pedantic,请确保其如下所示:

function() {
    int i;
    i = 0;

    someCode();
}

您仍然可以初始化变量,只是在声明变量之前不能放置代码。
SS安妮

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上测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.