ISO C90禁止混合声明和代码...但是在某些情况下允许?

Kar*_*sen 7 c declaration c89 statements

我正在使用以下标志(其中cc是gcc 4.2或clang 8.0):

$ cc -Wall -Werror -pedantic -ansi -std=c89 main.c

(我知道-ansi标志在这种情况下有点多余)

以下给了我预期的错误

main.c:31:8: warning: ISO C90 forbids mixing declarations and code [-Wdeclaration-after-statement]
  vec3 abc = {0};
Run Code Online (Sandbox Code Playgroud)
int main()
{
  vec3 a = {0};
  vec3 b = {0};

  Vec3(2, 2, 2);

  vec3 abc = {0}; // Declared after a function call

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,以下内容不

int main()
{
  vec3 a = Vec3(0, 1, 2);
  vec3 b = Vec3(0, 1, 2);

  vec3 abc = {0}; // Declared after a function call

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当然,使用函数初始化变量仍然算作混合声明和代码吗?

Vec3功能非常基础。没有设置内联标志,等等。

vec3 Vec3(float x, float y, float z)
{
  vec3 rtn = {0};

  rtn.x = x;
  rtn.y = y;
  rtn.z = z;

  return rtn;
}
Run Code Online (Sandbox Code Playgroud)

Vla*_*cow 9

在此代码段中

  vec3 a = Vec3(0, 1, 2);
  vec3 b = Vec3(0, 1, 2);

  vec3 abc = {0}; // Declared after a function call
Run Code Online (Sandbox Code Playgroud)

只有声明。没有任何陈述。用于初始化变量的函数调用是表达式。它们不是陈述。

看来这个警告

警告:ISO C90禁止混合声明和代码

令人困惑。写那个会更正确

警告:ISO C90禁止混合声明和声明

例如,即使是多余的分号也会引入null语句。因此,一般而言,即使对于以下代码段,编译器也应发出警告

  vec3 a = Vec3(0, 1, 2);;
                       ^^^^
  vec3 b = Vec3(0, 1, 2);
Run Code Online (Sandbox Code Playgroud)


Jon*_*ler 5

第二个函数具有三个带有初始化程序的连续变量定义-没问题。

C90(C89)所不允许的是在语句之​​后进行声明—在给定的语句块({和之间})中,声明必须全部在任何语句之前(非声明)。一个普通的函数调用(不是初始化程序的一部分)是一条语句。

因此,用于报告问题的GCC选项为-Wdeclaration-after-statement