简体   繁体   中英

C++ allows redefinition of global (const) variable?

I'm a bit confused by global constants. My (beginner level) understanding is that 'global' variables are defined outside of a block and have program scope (source: http://www.learncpp.com/cpp-tutorial/42-global-variables/ ). But the program:

#include <iostream>

const double x=1.5;

int main(){
        std::cout << "1) x=" << x << std::endl;
        double x=2.5;
        std::cout << "2) x=" << x << std::endl;
        //const double x=3.5;
        return 0;
}

compiles in g++ (GCC, latest 64-bit version) without any problems, even with -Wall.

The output:

1) x=1.5
2) x=2.5

This is confusing to me. The fact that the first cout evaluates means that main recognises 'x' as a 'global' variable (it wasn't defined in main's scope). If that is the case, why does it let me redefine 'x'?

Then, if you uncomment the commented third declaration, g++ throws up a redeclaration error. Meaning, my first declaration can't have been 'global', in the sense I defined :S

edit: okay, question has nothing to do with global variables, but scopes: eg same problem in http://pastebin.com/raw.php?i=V5xni19M

#include <iostream>

const double x=1.5;

At this point in code, there is one object named x in the global scope, and it is of type const double .

int main(){
        std::cout << "1) x=" << x << std::endl;

At this point, there's still just one x visible (the global one), so that's what the name x refers to.

        double x=2.5;

At this point in code, you've introduced an object named x into the scope of main() . That scope is nested inside global scope, so now you have two objects named x :

  1. x in global scope of type const double

  2. x in the scope of main() of type double

The local x hides the global x . If you want to access the global x inside main() , you can refer to it as ::x .

    std::cout << "2) x=" << x << std::endl;
    double x=3.5;  //uncommented

No you're trying to introduce another object named x into the scope of main() . This is not possible, there already is one x in that scope, so it fails.

The second x is not a redefinition. It is hiding the global x . This is something to watch our for particularly when dealing with inheritance:

  struct Base 
  {
      void AwesomeFunction() { }
  };

  struct Derived : public Base
  {
      // This definition 'hides' Base::AwesomeFunction
      void AwesomeFunction() { }
  };

This hiding is only allowed because the second x is in a smaller scope than the global x . You get a redfinition error for the third x because the third and the second x are at the same scope 'level'.

Use ::x to access the global variable from your program. Right now you are making a local variable and a global. When you first print x it can't find a local one so it assumes you meant the global. After you make your local x it no longer defaults to the global.

What happens in your code is that the local variable takes precedence over the global variable if they take up the same name. You can use your global variable in any block throughout the program, while the local one will be disposed of at the end of its block (main). The compiler won't however let you declare two local variables of the same name in one block.

Declarations at an inner scope (like main) are allowed to shadow declarations at an outer scope (like file scope). Your third declaration of x is at the same scope as your second, so that is a redeclaration error.

You're not redefining the global variable; you're defining a separate local variable with the same name.

C++ allows you to reuse a name to declare something else in a narrower scope like this; technically, the declaration in the inner scope hides the one in the outer scope so that, between the declaration and the end of the function, x refers to the local variable. You can still access the global variable by qualifying it with its namespace: ::x .

The third declaration would try to reuse the name in the same scope, which is not allowed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM