-2

So I was looking through a few old C++ Test Books and I found the solution to one of the questions very cool! I have never seen this "syntax" before and wanted to ask if anyone knows how it actually works and why it isnt taught widely!


Question: Give the output to the following code ->

int g =10; //TAKE NOTE OF THIS VARIABLE

void func(int &x, int y){
    x = x-y;
    y = x*10;
    cout << x << ',' << y << "\n";
}

void main(int argc, char** argv){
    int g = 7;    //Another NOTE
    func(::g,g); // <----- "::g" is different from "g"
    cout << g << ',' << ::g << "\n";

    func(g,::g);
    cout << g << ',' << ::g << "\n";
}

The Output:

3,30

7,3

4,30

4,3


My question was how does the "::(variable)" syntax work exactly? It gets the variable stored outside of the main but where is that memory stored(Stack/Heap)? Can we change the value of that "Global" variable through pointers?

I thought this might allow for some really cool implementations, and wanted to share this knowledge with those like me did not know of this :)

Shrey
  • 671
  • 7
  • 14
  • 4
    Global variables are frowned upon because you cannot establish invariants for them (everyone can access them), and you need unique names. The `::` is called scope resolution operator, it is typically used to access namespaces (such as the global namespace). – dyp Feb 14 '14 at 17:06
  • It's like doing `std::cout` to access `cout` in the `std` namespace. – Paul Feb 14 '14 at 17:07

6 Answers6

5

My question was how does the "::(variable)" syntax work exactly?

:: is the scope resolution operator. With the name of a class or namespace before it, it means that the name after it is scoped inside that class or namespace. With, as here, nothing before it, it means that the name after it is scoped in the global namespace; that is, it's declared outside any classes, functions, or namespaces.

Often, you can refer to a global variable by name without ::. It's needed here since the global is hidden by a local variable with the same name. This is one reason to avoid global variables: the meaning of code can change if you add a declaration that hides it.

where is that memory stored(Stack/Heap)?

It's in static storage, neither on a stack nor the heap. The storage is allocated when the program begins, and lasts until it ends.

If the variable has a complicated type, it might not be initialised until some time after the program starts; and you might get obscure and painful bugs when your code uses it before initialisation. This is another reason to avoid global variables.

Can we change the value of that "Global" variable through pointers?

Yes. Your example does that, albeit with a reference rather than a pointer. It can also be changed directly, e.g. ::g = 42;, by any code at any time, so it's hard to reason about the state of a program that contains them. This is yet another reason to avoid global variables.

I thought this might allow for some really cool implementations

Global variables are nearly always more trouble than they're worth, for the reasons I've mentioned here and others. I'd avoid them if I were you.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • Yes Ty very much! I seem to have been mistakenly using namespace std, which i have found is not the correct norm apparently! This makes a lot more sense now :) – Shrey Feb 14 '14 at 17:52
  • 1
    @Scarecrow: `namespace std` is where the standard library lives, to keep it separate from anything you declare in the global namespace or your own namespaces. You shouldn't declare anything in there yourself. – Mike Seymour Feb 14 '14 at 17:54
1

Plain g means "use the most local g", ::g means use the global g.

More general, example::g means "use the g from namespace example".

Also, if you can somehow avoid it (and you usually can), do not use global variables and do not use trickery like this, it is very error-prone.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
0

Static variables are in a category of their own: they're not really on "the stack" or "the heap." There is a specific section of your process' memory space set aside to hold static variables which is distinct from the stack or the heap. See the link given for a full discussion.

You can still use this variable as you would any other, and you can indeed take a pointer to it and change its value via the pointer.

As others have suggested, don't get too excited about this: global variables are frowned upon. They are often a sign of poor design, and there are many real-world disadvantages and pitfalls.

Community
  • 1
  • 1
TypeIA
  • 16,916
  • 1
  • 38
  • 52
0

The :: in C++ is called the scope resolution operator. It's documented in many places (here for example). It provides a way to name variables that may be in a different scope than the current code. There is an optional scope specification in front of the :: (A::g, for instance, for a namespace A); no scope specification indicates the "global" scope. Anything you can do with variables (including modifying through pointers) can be done with variables that have a scope resolution operator. Where the variable lives is defined by what scope it was defined in.

Static variables (global or not) are in one of a couple of places, depending on the compiler and possibly on how they are initialized. See, for example, this thread.

Community
  • 1
  • 1
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • OP's question was more about the nature of static variables, not the `::` operator. – TypeIA Feb 14 '14 at 17:11
  • @dvnrrs - Where did you get that idea from? From OP's question: _"My question was how does the "::(variable)" syntax work exactly?"_ – Ted Hopp Feb 14 '14 at 17:12
  • Yes; he then goes on to say "It gets the variable stored outside of the main but where is that memory stored(Stack/Heap)?" – TypeIA Feb 14 '14 at 17:12
  • @dvnrrs - Good point. I added a bit about global variable storage. – Ted Hopp Feb 14 '14 at 17:17
0

By prepending :: to a variable or function, you tell the compiler that it should look for this variable/function in the global namespace, i.e. outside the function's scope.

JorenHeit
  • 3,877
  • 2
  • 22
  • 28
0

:: is the scope resolution operator. If you have some bar identifier declared within the foo namespace, you can use foo::bar to denote it. If you have the scope resolution operator with nothing preceding it, then it denotes the global namespace. That's why ::g refers to the g in the global namespace.

It gets the variable stored outside of the main but where is that memory stored(Stack/Heap)? Can we change the value of that "Global" variable through pointers?

I'm not sure why these questions arose. They are using the global variable g just as you would be able to if the local g wasn't declared. The only reason the :: is required is because there are two g identifiers. You can do pretty much anything with it that you would be able to do with any other object with the same type.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324