ISO C90 禁止混合声明和代码……但在某些情况下允许这样做?
ISO C90 forbids mixing declarations and code... but allows it in certain instances?
我正在使用以下标志(其中 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};
int main()
{
vec3 a = {0};
vec3 b = {0};
Vec3(2, 2, 2);
vec3 abc = {0}; // Declared after a function call
return 0;
}
但是,下面没有
int main()
{
vec3 a = Vec3(0, 1, 2);
vec3 b = Vec3(0, 1, 2);
vec3 abc = {0}; // Declared after a function call
return 0;
}
确定用函数初始化变量仍然算作混合声明和代码?
Vec3 函数非常基础;没有设置内联标志等
vec3 Vec3(float x, float y, float z)
{
vec3 rtn = {0};
rtn.x = x;
rtn.y = y;
rtn.z = z;
return rtn;
}
第二个函数具有三个带有初始值设定项的连续变量定义 — 这不是问题。
C90 (C89) 不允许在语句之后声明 — 在给定的语句块内(在 {
和 }
之间),声明必须全部在任何语句之前(非声明)。一个普通的函数调用,不是初始化程序的一部分,是一个语句。
这就是为什么报告问题的 GCC 选项是 -Wdeclaration-after-statement
。
您误解了约束条件。我们可以有带有初始值设定项的声明;第一个非声明语句标志着声明的结束,在那之后我们不允许在该范围内进行更多声明。
非声明语句可以是表达式语句(如上)、复合语句(例如if
或while
)或块。
在此代码段中
vec3 a = Vec3(0, 1, 2);
vec3 b = Vec3(0, 1, 2);
vec3 abc = {0}; // Declared after a function call
只有声明。没有声明。用于初始化变量的函数调用是表达式。它们不是陈述。
好像是这个警告
warning: ISO C90 forbids mixing declarations and code
令人困惑。写
会更正确
warning: ISO C90 forbids mixing declarations and statements
例如,即使是多余的分号也会引入空语句。所以通常编译器应该发出警告,即使是下面的代码片段
vec3 a = Vec3(0, 1, 2);;
^^^^
vec3 b = Vec3(0, 1, 2);
我正在使用以下标志(其中 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};
int main()
{
vec3 a = {0};
vec3 b = {0};
Vec3(2, 2, 2);
vec3 abc = {0}; // Declared after a function call
return 0;
}
但是,下面没有
int main()
{
vec3 a = Vec3(0, 1, 2);
vec3 b = Vec3(0, 1, 2);
vec3 abc = {0}; // Declared after a function call
return 0;
}
确定用函数初始化变量仍然算作混合声明和代码?
Vec3 函数非常基础;没有设置内联标志等
vec3 Vec3(float x, float y, float z)
{
vec3 rtn = {0};
rtn.x = x;
rtn.y = y;
rtn.z = z;
return rtn;
}
第二个函数具有三个带有初始值设定项的连续变量定义 — 这不是问题。
C90 (C89) 不允许在语句之后声明 — 在给定的语句块内(在 {
和 }
之间),声明必须全部在任何语句之前(非声明)。一个普通的函数调用,不是初始化程序的一部分,是一个语句。
这就是为什么报告问题的 GCC 选项是 -Wdeclaration-after-statement
。
您误解了约束条件。我们可以有带有初始值设定项的声明;第一个非声明语句标志着声明的结束,在那之后我们不允许在该范围内进行更多声明。
非声明语句可以是表达式语句(如上)、复合语句(例如if
或while
)或块。
在此代码段中
vec3 a = Vec3(0, 1, 2);
vec3 b = Vec3(0, 1, 2);
vec3 abc = {0}; // Declared after a function call
只有声明。没有声明。用于初始化变量的函数调用是表达式。它们不是陈述。
好像是这个警告
warning: ISO C90 forbids mixing declarations and code
令人困惑。写
会更正确warning: ISO C90 forbids mixing declarations and statements
例如,即使是多余的分号也会引入空语句。所以通常编译器应该发出警告,即使是下面的代码片段
vec3 a = Vec3(0, 1, 2);;
^^^^
vec3 b = Vec3(0, 1, 2);