-2

I listed my two questions below with C++ code. Thank you in advance.

(1) Using "extern" fails to find outside static symbols. Why?

config.cpp

static int config_id = 123;

run.cpp

extern int config_id;

void exec() {
  int id = config_id;  // "config_id" symbol not found!!! 
                       // It works when config_id in config.cpp is not static.
}

(2) If int config_id = 123 is in a namespace namespace app, how to correctly reference it?

config.cpp

namespace app {
  int config_id = 123;
}

run.cpp

using namespace app;

extern int config_id;  // Fail to refer to the symbol in config.app. 
                       // How to fix?
lichgo
  • 523
  • 1
  • 6
  • 16
  • 5
    (1) is pretty much the point of `static` (at file scope). What do you think `static` does? –  Jul 13 '14 at 14:37
  • The `static` declaration in `config.cpp` makes the variable file-local, so it can't be accessed from another file. – Barmar Jul 13 '14 at 14:37
  • Also `extern` doesn't resolve using the the namespace defaults though, you have to be unambiguous: `extern int app::config_id;` – πάντα ῥεῖ Jul 13 '14 at 14:39

3 Answers3

3

static explicitly says that this config_id is only local to this file (translation unit to be precise), and is unrelated to any other variable with the same name. Your first example shows it doing its job.

In the second example, the variable config_id at global scope is different from the variable in namespace app.

You could do

namespace app {
  extern int config_id;
}

But you shouldn't be doing any of this - declare things in header files, define the in exactly one place, and it will all just work.

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
  • The "use header files" is pretty much the same conclusion as my answer, but unless the OP knows how to avoid using `static` and to make the declaration in the right namespace in the header file, it still won't help them. :-) – C. K. Young Jul 13 '14 at 14:41
  • Are you sure we don't need `extern` there? I thought a bare `int config_id;` would constitute a *definition* and hence cause ODR trouble? –  Jul 13 '14 at 14:42
2

The best way to enable run.cpp to refer to things defined in config.cpp is to create a config.h (or config.hpp) header file. That way, changes to config.cpp is easier to keep in sync, you only have to update config.h.

Anyway, to answer your questions:

  1. In the first case, the static actually makes your variable invisible to other translation units. This is how static works for top-level variables.
  2. In the second case, you still need a declaration that config_id is inside the app namespace:

    namespace app {
        extern int config_id;
    }
    
C. K. Young
  • 219,335
  • 46
  • 382
  • 435
2

(1) When you are using the static keyword in this context, you are declaring config_id to have "internal linkage", which means that it is only visible to it's compilation unit, config.cpp. If you want that variable to be visible in run.cpp, omit, the static keyword, as config_id will then have external linkage by default. See What is external linkage and internal linkage?.

(2)As Chris stated, config_id has been declared in the app namespace, so you will need to indicate so in "run.cpp"

Community
  • 1
  • 1
drewbarbs
  • 345
  • 3
  • 9