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;
/* ... */
}
答案 0 :(得分:3)
在C89 / C90中,在非变量声明的代码之后声明变量是不合法的。
void foo()
{
int i = 0;
i = 2; // Does not declare a variable.
int j = 10; // Not legal.
}
上面的代码适用于gcc。但是,如果您使用-pedantic
标志,您将看到一条类似于以下内容的警告消息:
soc.c:5:4: warning: ISO C90 forbids mixed declarations and code [-Wpedantic]
int j = 10;
但是,您可以拥有任意数量的变量声明。初始化变量的代码可以使用语言提供的任何方法。你所有的例子都很好。
答案 1 :(得分:1)
您的所有示例都是合法的,可以安全地与符合ANSI-C的编译器一起使用。
使用gcc
和-std=c89
在-pedantic
中编译代码不会产生任何警告。
答案 2 :(得分:1)
C89不允许在同一范围内混合声明和语句。我们在这里指的是函数内部的声明和语句,因为C语句中的函数不允许使用语句。
int a = foo(a, b); /* declared at block-scope */
上面的行是(有效的C89)声明,而不是声明所以你的所有函数f1,f2,f3和f4都是有效的C89。
但是,您可以在不同的范围内混合声明和语句:
void bar(void)
{
int i = 0; /* declaration */
i++; /* statement */
{
int j = 0; /* declaration */
j++; /* statement */
}
}
上述功能有效C89。
答案 3 :(得分:1)
C99标准的前言本身提及"混合声明和代码"作为C90的变化之一。这是恕我直言,这是一个糟糕的选择,因为它根本不清楚什么"代码"手段。它可以轻松引用可以出现在C源文件中的所有内容。
C99所做的实际更改是允许在一个块中混合声明和语句。 声明和语句之间的区别由语言语法明确定义。
您的一个示例中的行:
int y = time(NULL);
是声明,而不是声明,即使它导致在运行时执行某些代码。是否存在初始化程序,以及该初始化程序是否为常量表达式,不会影响某些内容是否被视为声明。
您的问题中的所有四个示例在C89 / C90,C99和C11中都有效。在每种情况下,块只包含声明,没有语句。
如果要在C90中混合声明和语句,可以通过引入嵌套块来实现:
void func(void) {
int x = 1; /* a declaration */
x = 2; /* a statement; no declarations may follow in C90 */
{
int y = 3; /* a declaration */
y = 4; /* a statement */
}
}
内部阻止它本身就是一个声明。因为它是一个声明,它可以出现在该上下文中。因为它是一个复合语句,它本身可以包含一系列声明,后跟一系列语句。
即使在C99或C11中,引入这样的嵌套块也是有利的。 y
的范围和生命周期在包含其声明的块的结束}
处结束。限制声明的范围可以使代码更容易理解。
(有点背景:C89是ANSI在1989年发布的标准.ISO采用了它,文档中有一些变化,但没有用它描述的语言,如C90.ISO发布了更新标准,C99,然后由ISO.ISO采用另一个更新的标准C11,它也被ANSI采用。根据ANSI和ISO,2011标准是当前版本,所有早期版本都已过时。但由于历史原因,短语& #34; ANSI C"通常是指1989年和1990年版所描述的语言。我通常试图避免使用短语" ANSI C"而是指#34; ISO C" ,如果它是相关的,加上出版年份。)
答案 4 :(得分:0)
使用以下代码对C89 / 99版本差异的补充观察:
(C标准的C99扩展似乎在可以放置其他声明的地方变得不那么迂腐)
int main()
{
int a; //declaration only
int b; //declaration only
b = 5; //assignment only (no declaration)
int c; //declaration only (fails C89, Compiles C99)
return 0;
}
下图说明了使用C89设置时的错误,以及在赋值语句后尝试声明时的错误。 (当设置为使用C99时,代码编译时没有错误)
答案 5 :(得分:-2)
F1,f2,f3有效但f4不是因为声明和定义是混合的