【问题标题】:ISO C90 forbids mixed declarations and code in CISO C90 禁止在 C 中混合声明和代码
【发布时间】:2012-10-28 18:51:48
【问题描述】:

我是这样声明一个变量的:

int i = 0;

我收到警告:

ISO C90 禁止混合声明和代码

我该如何解决?

【问题讨论】:

  • 这听起来像 GCC 的 -pedantic 或 -std=c89,在这种情况下,您可以根据需要使用 -std=gnu99 进行编译。
  • 如果您使用 gcc,您可以指定使用允许混合声明和代码的 C99(标志 -std=c99)。
  • 一种选择是停止编译到一个已有 22 年历史的标准,甚至替换已被替换。
  • @StephenCanon,请告诉微软。 :)
  • @hmjd:微软对发布 C 编译器没有兴趣;这可能不会改变。幸运的是,有许多针对其他供应商提供的平台的非常好的编译器。

标签: c variables


【解决方案1】:

我认为你应该将变量声明移到块的顶部。即

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

到

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

【讨论】:

  • ... 或打开一个新的上下文:{foo(); {int i=0; bar();}}
  • @alk s/context/block 在 C 标准中就是这么称呼的。
  • @Johan Kotlinski 但为什么这很重要?
  • @ocean800 C90 规范规定不能在同一块中的非声明之后再进行声明。
【解决方案2】:

在 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 或更高版本,您需要找到一个支持的其他编译器,或者重写您的代码,以便所有声明都位于任何语句之前块内。

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 这个答案充其量是不完整的。它确实解决了问题,但没有解释导致它的原因。此答案不包括无法使用较新的编译器的情况(多种可能的原因......)或无法将选项切换到编译器的构建环境。投反对票,因为我不同意这是“真正的”答案。
    • 在某些情况下,-std=gnu89 在编译 linux 内核模块时使用。
    【解决方案4】:

    确保变量位于块的顶部,如果您使用-ansi-pedantic 编译它,请确保它看起来像这样:

    function() {
        int i;
        i = 0;
    
        someCode();
    }
    

    【讨论】:

    • 你仍然可以初始化变量,只是不能在声明之前放置代码。
    【解决方案5】:

    要诊断真正触发错误的原因,我会首先尝试删除= 0

    • 如果错误被触发,那么声明很可能在代码之后。

    • 如果没有错误,则可能与 C 标准执行/编译标志或...其他有关。

    无论如何,在当前作用域的开头声明变量。然后,您可以单独初始化它。事实上,如果这个变量值得拥有自己的范围 - 在 {} 中划定它的定义。

    如果 OP 可以澄清上下文,那么就会有更直接的回应。

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-08
        相关资源
        最近更新 更多