在作用域的开头声明C89局部变量?

4

我试图在ANSI C中完成这个:

include <stdio.h>
int main()
{
    printf("%d", 22);
    int j = 0;
    return 0;
}

这在 Microsoft Visual C++ 2010(ANSI C 项目)中不起作用。你会收到一个错误提示:
error C2143: syntax error : missing ';' before 'type'

这是有效的:

include <stdio.h>
int main()
{
    int j = 0;
    printf("%d", 22);
    return 0;
}

现在我在很多地方读到,你必须在代码块中变量存在的开始处声明变量。这对于ANSI C89来说通常是真的吗?

我发现很多论坛上的人都给出了这个建议,但我没有在任何“官方”来源(如GNU C手册)中看到它被写下来。

3个回答

5

ANSI C89要求变量在作用域开始时声明。这在C99中得到了放宽。

当您使用-pedantic标志时,在gcc中可以清晰地看到这一点,该标志更严格地执行标准规则(因为默认为C89模式)。

请注意,这是有效的C89代码:

include <stdio.h>
int main()
{
    int i = 22;
    printf("%d\n", i);
    {
        int j = 42;
        printf("%d\n", j);
    }
    return 0;
}

但是使用大括号来表示作用域(因此变量的生命周期)似乎并不特别流行,因此C99 ...等等。


4
现在我在许多地方都看到,你必须在代码块中声明变量,变量存在于其中。这在ANSI C 89中通常是正确的吗?
是的,在C89/C90标准的复合语句语法中,这是必需的:
(C90, 6.6.2 复合语句或块) 语法: compound-statement { declaration-list_opt statement-list_opt }
声明必须在块内语句之前。
C99通过允许在块中混合声明和语句来放宽了这一点。在C99标准中: (C99, 6.8.2 复合语句) 语法: compound-statement: { block-item-list_opt } block-item-list: block-item block-item-list block-item block-item: declaration statement

3
这在C89中是绝对正确的。(您最好查看语言的文档,例如书籍和标准。编译器文档通常仅记录编译器支持的语言与ANSI C之间的差异)。
然而,许多“C89”编译器允许您在块的几乎任何位置放置变量声明,除非将编译器置于严格模式。这包括GCC,可以使用 -pedantic 将其置于严格模式。Clang默认为C99目标,因此 -pedantic 不会影响您是否可以将变量声明与代码混合使用。
我很抱歉,MSVC对C的支持相当差。它只支持带有一些扩展的C89(旧版!)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接