C89(C90,ANSI-C)不允许将变量声明与代码混合。我想知道变量初始化在多大程度上被认为是“代码”。
也许只有用常量表达式初始化才有效?
具体来说,如果我正在编写C代码,并且我希望安全(最大化与ANSI-C编译器的兼容性),那么下面的代码应该被认为是安全的吗?
void f1(void) {
int x = 30;
int y = 40;
int z;
/* ... */
}
void f2(void) {
int x = 30, y = 40;
int z;
/* ... */
}
#define MYCONST (90)
void f3(void) {
int x = 3;
int y = 4 + MYCONST;
int z;
/* ... */
}
void f4(void) {
int x = 3;
int y = time(NULL);
int z = 10 + x;
/* ... */
}
5条答案
按热度按时间bvjxkvbb1#
下列情况是否应视为安全?
您发布的所有代码都是安全的。
1.您可以在任何范围内拥有任意数量的变量声明。
1.初始化变量的代码可以使用语言提供的任何方法。
但是,在不是变量声明的代码之后声明变量是不法律的的。
上面的代码适用于gcc,但是,如果使用
-pedantic
标志,则会看到一条警告消息,如下所示:2nc8po8w2#
C89不允许在同一作用域中混合声明和语句。我们这里指的是函数内部的声明和语句,因为C中不允许在函数外部使用语句。
上面一行是一个(有效的C89)声明,而不是一个语句,所以你所有的函数f1,f2,f3和f4都是有效的C89。
但是,您可以在不同的作用域中混合声明和语句:
上述函数在C89中有效。
jgovgodb3#
C99标准的前言本身提到“混合声明和代码”是C90的一个变化。恕我直言,这是一个糟糕的措辞,因为根本不清楚“代码”的意思。它可以很容易地指C源文件中出现的任何东西。
C99所做的实际改变是允许在一个块中混合声明和 * statement *。declaration 和 statement 之间的区别由语言语法明确定义。
下面是您的示例中的一行:
是声明,而不是语句,即使它会导致在运行时执行某些代码。初始值设定项的存在与否,以及该初始值设定项是否为常量表达式,都不会影响某项是否被视为声明。
您问题中的所有四个示例在C89/C90、C99和C11中都有效。在每种情况下,代码块只包含声明,不包含语句。
如果你想在C90中混合声明和语句,你可以通过引入嵌套块来实现:
内部代码块本身就是一个语句,因为它是语句,所以它可以出现在上下文中,因为它是复合语句,所以它可以包含一系列声明,后面跟着一系列语句。
即使在C99或C11中,引入这样的嵌套块也是有利的。
y
的作用域和生存期在包含其声明的块的结束}
处结束。限制声明的作用域可以使代码更容易理解。(背景介绍:C89是ANSI在1989年发布的标准,ISO采用了它,在文档中做了一些更改,但没有在它描述的语言中做更改,作为C90。ISO发布了一个更新的标准C99,然后被ISO采用。ISO发布了另一个更新的标准C11,也被ANSI采用。根据ANSI和ISO,2011标准是当前的标准,而且所有早期版本都已过时。但由于历史原因,短语“ANSI C”通常指的是1989年和1990年版本描述的语言。我通常尽量避免短语“ANSI C”,而是指“ISO C”,如果相关的话,再加上出版年份。)
py49o6xq4#
您的所有示例都是法律的的,可以安全地用于符合ANSI-C的编译器。
使用
-std=c89
和-pedantic
在gcc
中编译代码不会生成警告。hjzp0vay5#
F1、f2、f3有效,但f4无效,因为声明和定义是混合的