简体   繁体   English

ISO C90 禁止混合声明和代码……但在某些情况下允许这样做?

[英]ISO C90 forbids mixing declarations and code... but allows it in certain instances?

I am using the following flags (where cc is either gcc 4.2 or clang 8.0):我正在使用以下标志(其中 cc 是 gcc 4.2 或 clang 8.0):

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

(I know the -ansi flag is a bit redundant in this case) (我知道 -ansi 标志在这种情况下有点多余)

The following gives me the expected error以下给了我预期的错误

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

  Vec3(2, 2, 2);

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

  return 0;
}

However, the following does not然而,以下不

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

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

  return 0;
}

Surely initializing a variable with a function still counts as mixing declarations and code?当然用函数初始化变量仍然算作混合声明和代码?

The Vec3 function is very basic; Vec3 函数非常基础; no inline flag set, etc.没有内联标志集等

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

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

  return rtn;
}

In this code snippet在此代码段中

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

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

there are only declarations.只有声明。 There are no statements.没有声明。 Function calls used to initialize the variables are expressions.用于初始化变量的函数调用是表达式。 They are not statements.它们不是陈述。

It seems this warning似乎这个警告

warning: ISO C90 forbids mixing declarations and code警告:ISO C90 禁止混合声明和代码

is confusing.令人困惑。 It would be more correctly to write that这样写会更正确

warning: ISO C90 forbids mixing declarations and statements警告:ISO C90 禁止混合声明和声明

For example even a redundant semicolon introduces a null statement.例如,即使是多余的分号也会引入空语句。 So in general the compiler should issue a warning even for the following code snippet所以通常编译器应该发出警告,即使是下面的代码片段

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

The second function has three consecutive variable definitions with initializers — that isn't a problem.第二个函数具有三个带有初始值设定项的连续变量定义——这不是问题。

What C90 (C89) does not allow is a declaration after a statement — within a given statement block (between { and } ), the declarations must all precede any statements (non-declarations). C90 (C89) 不允许在语句之后声明 — 在给定语句块内( {}之间),声明必须全部位于任何语句(非声明)之前。 A plain function call, not part of an initializer, is a statement.一个普通的函数调用,不是初始化器的一部分,是一个语句。

That's why the GCC option for reporting on the problem is -Wdeclaration-after-statement .这就是为什么用于报告问题的 GCC 选项是-Wdeclaration-after-statement的原因。

You're misunderstanding the constraint.你误解了约束。 We can have declarations with initializers;我们可以有带有初始值设定项的声明; the first non-declaration statement marks the end of the declarations, and after that point we're not allowed more declarations in that scope.第一个非声明语句标志着声明的结束,在那之后我们不允许在该范围内进行更多声明。

Non-declaration statements can be expression-statements (as above), compound statements (such as if or while ) or blocks.非声明语句可以是表达式语句(如上)、复合语句(例如ifwhile )或块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM