Can't Use Structure in Global Scope

can't use structure in global scope

It's not that you "can't use structures in global scope". There is nothing special here about structures.

You simply cannot write procedural code such as assignments outside of a function body. This is the case with any object:

int x = 0;
x = 5; // ERROR!

int main() {}

Also, that backwards typedef nonsense is so last century (and not required in C++).

If you're trying to initialise your object, do this:

#include <iostream>

struct MyStruct
{
int x;
int y;
char t;
};

MyStruct co = { 1, 2, 'a' };

int main()
{
std::cout << co.x << '\t' << co.y << '\t' << co.t << std::endl;
}

Why can't you define struct members globally?

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();
^~~

Why is it not allowed to initialize a struct member in the global (file) scope, but it is OK to do it inside a function?

There is a syntactic difference between initialization and assignment. The presence of the = operator is only part of the story.

Initialization is part of a declaration, and declarations are allowed at file scope. The presence of one or more declaration specifiers (type specifiers like int or float, typedef names like S_t, storage class qualifiers like static, type qualifiers like const or volatile, etc.) tells the compiler that this is a declaration.

Otherwise, the presence of the = operator indicates that this is an assignment expression, and assignment expressions may only appear as part of a statement, and statements are only allowed within function bodies.

As for why you can't have statements outside of a function body, well, that's just how the languages C was derived from were designed.

Cannot declare global variable with the name of a struct

The issue here is fairly simple. You cannot redefine the meaning of a name in the same scope it is defined. To contrast, this would be valid

typedef struct foo{
char c;
}foo;

int main()
{
foo foo;
}

Following the declaration in the scope of main, the meaning of foo is altered. But when you do it in the same scope as the type alias, you are basically providing conflicting definitions.

Struct fields aren't in the scope of the type definition itself. So that's why those don't conflict either.

why can't you initialize values of structs outside of main() in c?

The form you've written is not initialization; it's an uninitialized (or rather default-initialized, to zero) declaration and definition followed by assignment statements outside of a scope where they're valid.

If you want to initialize the members by name, write:

struct coordinates point = {
.x = 5,
.y = 3,
};

Why can't I assign values to global variables outside a function in C?

This is a definition of a global variable, with the optional initialisation to a specific value:

int i = 8;

Note that it is not code which gets ever executed, the variable will just be set up to initially contain the 8. Either consider it "magic" (a helpful model for many things not really defined by the standard) or think of tables with values being copied to memory locations before any code is executed.

This is a piece of code which has no "frame" in which it is executed.

(Or you intend it to be. The compiler is of other opinion, see below.)

i = 9;

There is no function containing it. It is not clear when it should be executed. That is what the compiler does not like.

In C, all code has to be inside a function and will only be executed if that function is called, e.g. from main().

Other language, mostly those which execute "scripts" by interpreting them (instead of code being turned into executeables, e.g. by a compiler) allow to have code anywhere. C is different.

The compiler sees this differently:

i = 9;
  • it is not inside a function, so it cannot be code
  • it looks like a variable definition, assuming that you mean it to be an int, i.e. the default
  • but relying on defaults is not a good idea, so warn about missing type and that the default is used
  • also, if it is a definition, then it is the second one for i, now that is really wrong, so show an error and fail the compiling
  • just to be helpful, mention where the first definition of i is

That is how to read the compiler output you have quoted.

Arduino IDE does not allow struct variables outside a function

struct IDENTITY {
int identifier;
bool is_alive;
};

IDENTITY testguy = { 256, true };

void setup() {
testguy.identifier=6;
testguy.is_alive=false;
}

void loop() {
}

Works for me...

Accessing struct variables outside of function in C

Is the variable name only set to "thomas" within void setName()?

Yes. That's the essence of how local variables work

How would I make it so that if I give a value to a struct variable that that value is accessible globally?

Make struct Class setName; global by declaring it outside setName function. I suggest also giving it a different name - say, theClass.

You should also change setName to take both the name and struct Class on which you would like to set the name.

If I was to print out the variable name within int main() it would be blank, how would I make it print out "thomas"?

Once you move the declaration outside setName() function, you would be able to access it from anywhere you'd like.

struct Class {
const char *name;
int Hitdice, Str_Dice, Dex_Dice, Con_Dice, Int_dice, Wis_Dice, Cha_Dice, Skill_Points, level;
double BAB_Type;
struct Class *next_Class;
} theClass;

void setName(struct Class *myClass, const char* theName) {
myClass->name = theName;
}

int main() {
setName(&theClass, "thomas");
printf("%s\n", theClass.name);
return 0;
}

How to pass local structures to functions?

First of all you should really use proper prototypes that matched the function definitions.

Secondly, your example do pass a structure into the local variable hc in the function.

When function is running there are two distinct and separate structures in memory: The one in the main function, and the local in the function function.


To cover my bases, here are two answers for two other question that maybe is asked:

  1. You want to define the structure itself inside the main function, and then be able to use it in other functions.

    Something like

    int main(void)
    {
    struct hexColor
    {
    uint32_t white;
    // Other members omitted
    };

    struct hexColour hc;
    hc.white = 0xff;

    func(hc); // Assume declaration exist
    }

    void func(struct hexColour my_colour)
    {
    printf("White is %u\n", my_colour.white);
    }

    This is not possible. The structure hexColour is defined inside the main function only. No other function can use that structure. It doesn't matter if you pass a pointer or not, the structure hexColour still will only exist inside the main function only.

  2. Emulate pass-by-reference by passing a pointer to a structure object. Like

    struct hexColor
    {
    uint32_t white;
    // Other members omitted
    };

    int main(void)
    {
    struct hexColour hc;
    hc.white = 0xff;

    // Assume declaration of function exists
    func(&hc); // Emulate pass-by-reference by passing a pointer to a variable
    }

    void func(struct hexColour *colourPointer)
    {
    colourPointer->white = 0x00;
    }

    This is possible, because then the structure hexColour exists outside the main function, in the global scope. All functions declared and defined after the structure definition may use the structure and its members.



Related Topics



Leave a reply



Submit