7

Suppose I have a global variable, and I want to assign another variable to it. I've found out that you can assign another value to a global variable inside a function:

int i = 8;

int main(void)
{
  i = 9;     /* Modifies i */
  return 0;
}

However, assignment of the global variable outside of a function does not work!

int i = 8;

i = 9;  /* Compiler error */

int main(void)
{
  return 0;
}

I get the following error message:

warning: data definition has no type or storage class
warning: type defaults to 'int' in declaration of 'i'
  error: redefinition of 'i'
note: previous definition of 'i' was here
int i = 8;
    ^

Why is this happening?

Galaxy
  • 2,363
  • 2
  • 25
  • 59
  • 2
    When would you expect that to execute when it's outside of a function? – DeiDei Jun 02 '18 at 21:21
  • 8
    Only definitions and declarations are allowed outside of functions. You can't have general statements. That's how the language is specified. – Some programmer dude Jun 02 '18 at 21:23
  • This isn't a good question for SO. The only reasonable answer is a variation on the theme of "because that's the way the language is designed" — and asking why it's designed like that is not constructive; it has been that way since forever and isn't going to change on that issue. Once upon an ancient standard, you might have been able to write `i = 9;` at file scope and it would implicitly be of type `int`, but GCC 8.1.0 warns `data definition has no type or storage class` with `-std=c90`, with or without `-pedantic`. – Jonathan Leffler Jun 02 '18 at 21:28
  • Instead of `int i = 8; i = 9;` have you considered the more effective `int i = 9;` instead? Code execution begins at `main()`. – Weather Vane Jun 02 '18 at 21:29
  • @DeiDei That's a valid point actually. – Galaxy Jun 02 '18 at 21:41

1 Answers1

11

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.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • It is not only that "relying to defaults" is no good - this form isn't even supported in C89, and GCC now compiles in gnu11 mode where the implicit int has looong gone. – Antti Haapala -- Слава Україні Jun 04 '18 at 00:02
  • @AnttiHaapala I would agree t consider it an error. OPs compiler (whatever it is) clearly says "warning". It would be interesting to know, whether it would compile if the double definition would not be there. – Yunnosch Jun 04 '18 at 05:38