问题
When you define a struct globally, why can't you define the structure members globally as well (outside of using the initializer syntax)? The error I'm getting from clang is that system_1 has an "unknown type name".
If you define the struct within a function, such as main(), then you don't run into any issues.
typedef struct Light_System {
int redLightPin;
int yellowLightPin;
int blueLightPin;
} Light_System;
Light_System system_1;
# "Light_System system_1 = {4, 0, 0}" works
system_1.redLightPin = 4; # doesn't work
int main(int argc, char *argv[]) {
# placing everything in here works
# placing just "system_1.redLightPin = 4;" here makes it work.
printf("%d\n", system_1.redLightPin);
return 0;
}
I would expect that I would be able to define the structure's members within the global scope.
回答1:
When you define a struct globally, why can't you define the structure members globally (outside of using the initializer syntax)?
Because what you're trying to do is not a definition or an initialization. It's an assignment. You can declare, define and initialize in global scope, but not assign.
This is not only for structs. It goes for variables too. Outside a function, you can only declare and initialize variables. You cannot do regular assignments, or anything else for that matter. I'm not 100% sure of the details, but I'm fairly confident that you cannot do anything in global scope that cannot be done during compile time.
So this would work:
int x=5;
But not this:
int x;
x = 5;
Well, actually it is valid but will yield cryptic warnings about warning: data definition has no type or storage class and warning: type defaults to ‘int’ in declaration of ‘x’ However, just because it compiles, it will not do what you think it will. Actually, cryptic warnings that you don't understand is very often a good indicator that the code will do something that you neither want nor understand. What this code does is an implicit redeclaration of x followed by an initialization. It's allowed if it has not been initialized earlier, so this not valid:
int x = 3;
x = 5; // Not ok, because x is already initialized
And the error message here makes it clear why the previous example compiled: error: redefinition of ‘x’.
Similarly, this is not valid either:
int x = foo();
It gives this error:
main.c:3:7: error: initializer element is not constant
int x = foo();
^~~
回答2:
As others have stated. You can not assign in a global scope. But you can initialise. So if you want to initialise struct members globally, you can try it like this.
#include <stdio.h>
typedef struct Light_System {
int redLightPin;
int yellowLightPin;
int blueLightPin;
} Light_System;
Light_System ls = {10,5,3};
int main()
{
printf("%d %d %d",ls.redLightPin,ls.yellowLightPin,ls.blueLightPin);
}
That should compile.
So if you're wondering why this happens, it's because global variables are stored in the .data section of an application with a given value at compile time. But assignments are instructions which can only be executed within the scope of a function. So what gets compiled keeps their time value.
回答3:
You can't execute statements outside of a function in C or C++. But you can use C99-style "designated initializers" in a lot of compilers (not all):
Light_System system_1 = {
.redLightPin = 4
};
This will become standard in C++20, but as the same syntax has existed for years in C, many compilers allow it in C++ as well.
Ref: https://en.cppreference.com/w/cpp/language/aggregate_initialization
来源:https://stackoverflow.com/questions/56617945/why-cant-you-define-struct-members-globally