6

In C++, it is advisable to declare global variables inside the main program, or outside it, before everything else? I mean, what is the difference between

#include <iostream>

int variable;

int main()
{    //my program
     return 0;
}

and

#include <iostream>

int main()
{
     int variable;
     //my program
     return 0;
}

In which case should I use which one?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Jeffrey Lebowski
  • 281
  • 1
  • 2
  • 12
  • 4
    You should almost never declare variables outside of functions. It's a bad practice that leads to questionable designs. – n. m. could be an AI Apr 07 '16 at 16:53
  • @πάνταῥεῖ, I do not neccessarily agree with duplicate. OP seems to be asking 'which is which', not 'which is better'. From the question itself it is not clear if OP understands what the global variable is. voting to reopen. – SergeyA Apr 07 '16 at 16:54
  • @n.m., care to say that to STL implementors? – SergeyA Apr 07 '16 at 16:55
  • @SergeyA not sure what you mean. – n. m. could be an AI Apr 07 '16 at 16:57
  • 1
    @n.m. He refers to stuff like `std::cout` aso. – πάντα ῥεῖ Apr 07 '16 at 16:59
  • @n.m. I mean, that there are several global variables in there. Is it a *bad design*? – SergeyA Apr 07 '16 at 16:59
  • 1
    @πάντα yes, I very much dislike how standard streams remember state across function invocations. Personally, I also dislike the very concept of standard streams, independently of the language. – n. m. could be an AI Apr 07 '16 at 17:09
  • @SergeyA Yes, I would say it is a bad design, in most cases. – n. m. could be an AI Apr 07 '16 at 17:09
  • @n.m., OK, point taken. How would you design a console output mechanism? – SergeyA Apr 07 '16 at 17:10
  • @SergeyA: I/O streams have nothing to with the "STL", nor with the containers/iterators/algorithms part of the standard library. – Christian Hackl Apr 07 '16 at 17:18
  • @SergeyA why not open and close these streams like any other files? – n. m. could be an AI Apr 07 '16 at 17:21
  • @ChristianHackl, the second part is both moot and wrong. It is moot because it is not relevant (not being part of stl algorithms has nothing to do with being part of STL), and it is wrong because there is a stream iterator. So it is part of iterators. The second part is also wrong, unless you can provide some proof. (STL means STandard Library for long time) – SergeyA Apr 07 '16 at 17:21
  • @n.m, and pass the stream object through the whole program? What would be the benefit? – SergeyA Apr 07 '16 at 17:21
  • @SergeyA: The stream iterator *uses* the library. It's not part of the library itself. As for the name "STL": http://stackoverflow.com/questions/5205491/whats-this-stl-vs-c-standard-library-fight-all-about/5205571#5205571 – Christian Hackl Apr 07 '16 at 17:23
  • @ChristianHackl, like I said, they are part of the same library. If you can support your claim using **standard** as a reference, I am open to discussion, otherwise there is no sense in continuing it. – SergeyA Apr 07 '16 at 17:25
  • @SergeyA no, open them when you need them, close when you are done. Passing them as paraeters to every function doesn't make a lot of sense. Though for objects that exist outside of the program, like standard streams, global handles are often convenient and not that problematic. – n. m. could be an AI Apr 07 '16 at 17:29
  • @n.m.. but how would you open them? What would be the argument to a function which returns any handle representing console output? – SergeyA Apr 07 '16 at 17:30
  • @SergeyA: `std::istream_iterator` and `std::ostream_iterator` are indeed part of the iterator library (section 24), but they are completely generic and not tied to standard I/O streams. As far as I see it, the only reference to `std::cin` and `std::cout` in that section is in an example in §24/6(1). The design and implementation of what you call "STL" does not require any global objects. – Christian Hackl Apr 07 '16 at 17:32
  • @SergeyA There are special names around like /dev/null and many others, they could have used something similar. – n. m. could be an AI Apr 07 '16 at 17:34
  • @ChristianHackl, what I (an many others) call STL is the library described in C++ Standard. This library uses global objects. – SergeyA Apr 07 '16 at 17:35
  • @n.m., where would this name come from? Will it be a **global variable** or a magic word ("gimme the console, please?"). Also, you can globally tie `cout` to `cerr`, replace the buffer of `cout`, (effectively redirecting it transparently to other callers), possibly do other stuff. How would all this work when you just request a new object every time? – SergeyA Apr 07 '16 at 17:39
  • @SergeyA /dev/null is a magic word and nobody seems to have any problem with that. So is "file descriptor 0" in the Unix world (it's just an integer 0). I'm not quite sure why you think other callers will necessarily appreciate your fiddling with *their* cout. The ability of *every* function to pull such tricks is precisely the reason why I dislike it. – n. m. could be an AI Apr 07 '16 at 21:36
  • A variable declared in main is automatic, not global. –  Dec 09 '22 at 15:18

2 Answers2

17

In the first case variable is accessible from all other functions in the file (i.e. it has global scope) whereas in the second case it is only accessible from within main. Generally, it's best to keep the amount of global variables you use to an absolute minimum to avoid polluting the variable space (among several other reasons).

Example:

Local to main,

int main(void) {
    int v;
    foo();
    return 0;
}

void foo() {
    v = 5; // compiler error: v not declared in this scope
}

Global,

int v;
int main(void) {
    foo();
    return 0;
}

void foo() {
    v = 5;   // compiles, v declared globally
}
sjrowlinson
  • 3,297
  • 1
  • 18
  • 35
  • 3
    The suggestion is right, but the reason (polluting the variable space) is probably low in the list of reasons. – SergeyA Apr 07 '16 at 16:49
  • Sorry, I got confused between a global variable, and a local variable in the main which still is local. – Jeffrey Lebowski Apr 07 '16 at 17:12
  • *In the first case variable is accessible from all other functions in the file (i.e. it has global scope) whereas in the second case it is only accessible from within main.* **Main** in here is **main()**, I believe. Is any possibility to write a code without involving this **main()**. Unless we are writing a function or using another function other that **main()** function, then your answer is correct. As I understood, the **main()** will always global. Thereby, the claim seems is not correct. – AirCraft Lover Apr 03 '19 at 08:21
2

variable in first case is a global variable. It can be accessed from functions other than, and including, main(); is guaranteed to live until program executes; and is set to 0 before first use.

In the second example, variable is a function local variable. It is not initialized to anything unless set by the programmer, can only be accessed within main(), and will be obliterated before main() terminates. That last point is not especially important for main(), but is much more important for other functions.

Jessie Westlake
  • 159
  • 2
  • 11
SergeyA
  • 61,605
  • 5
  • 78
  • 137