C 为什么不允许在全局(文件)范围内初始化结构成员,但可以在函数内初始化?

C 为什么不允许在全局(文件)范围内初始化结构成员,但可以在函数内初始化?,c,C,我在c文件的全局范围内声明了如下结构: typedef struct S_t { int i; char c; } S_t; S_t s1; 编译器不允许我初始化全局作用域中的每个成员,但可以在函数内初始化,例如main(): 我试着使用,gcc(C11,C18)以及g++。 但我总是得到一个错误: gcc:“错误:在“.”标记“之前应为“=”、“、”、“;”、“asm”或“属性” g++:“错误:“s4”未命名类型” 有人能解释一下为什么在全局范围内为s4.i赋值是非法的吗

我在c文件的全局范围内声明了如下结构:

typedef struct S_t {
    int i;
    char c;
} S_t;

S_t s1;
编译器不允许我初始化全局作用域中的每个成员,但可以在函数内初始化,例如main():

我试着使用,gcc(C11,C18)以及g++。 但我总是得到一个错误:
gcc:“错误:在“.”标记“
之前应为“=”、“、”、“;”、“asm”或“属性” g++:“错误:“s4”未命名类型”


有人能解释一下为什么在全局范围内为s4.i赋值是非法的吗?

您只能在函数之外进行常量表达式初始化

所有代码都必须在函数内部


s4.i=6不是一个初始化,它是一个必须位于函数体内部的赋值

初始化和赋值之间存在语法差异。
=
操作符的出现只是故事的一部分

初始化是声明的一部分,并且允许在文件范围内进行声明。一个或多个声明说明符(类型说明符,如
int
float
,typedef名称,如
S\u t
,存储类限定符,如
static
,类型限定符,如
const
volatile
,等等)的存在告诉编译器这是一个声明

否则,
=
运算符表示这是赋值表达式,赋值表达式只能作为语句的一部分出现,并且语句只能在函数体中出现


至于为什么不能在函数体之外有语句,那么,这就是C语言的设计原理。

在C中,所有代码都必须在函数内部。声明不算作代码。它们是规则。在函数之外,您所能做的几乎就是定义和初始化<代码>s4.i=6
是一项作业。“Y之外只能有X”在英语中是一个模棱两可的短语。它可能意味着“每个X必须在Y内”或“Y外的任何东西都必须是X”。此外,“常量表达式初始化”这一短语也不能解决这个问题。此代码中没有非常量表达式。问题很简单,语句(包括赋值)不能在函数之外;带有初始值设定项的声明可以在函数之外;说所有代码都必须在函数内部是不正确的,或者至少不清楚。声明和预处理指令也是代码。C语言中的区别不是代码和非代码,而是声明和语句(以及预处理指令)之间的区别。所有语句(不是代码)必须在函数内。答案非常精确!非常感谢@JohnBode!
S_t s1 = {5, 'c'};         // This is OK!
S_t s2 = {.i=5, .c='5'};   // OK, designated initialization
S_t s3 = {.c='c'};         // OK, partial designated  initialization
S_t s4;
// s4 = {5, 'c'};          //This is an error. Why?
// s4.i = 5;               //This is also an error.

int main(void) {
    s4.i = 6;              //This is fine..
    return 0;
}