PeteDD wrote: |
---|
wouldn't I see error messages earlier in the compile/build process than at link time? |
No. because it could have been defined in another translation unit.
A translation unit is basically a .cpp file + the content of all header files that it includes (directly or indirectly). Each translation unit is compiled independently of other translation units. That's why it doesn't know until link time whether the variable has been defined or not.
Note that the main reason why people use the extern keyword is to be able to use variables that have been defined in another translation unit. It's seldom useful to use extern for a variable that you know are always defined in the same translation unit.
PeteDD wrote: |
---|
It is in the initialize() function that I instantiate onewire and dallastemperature and start OneWireBus. |
In that case those two variables are local to the initialize() function and inaccessible from other functions (unless you pass them as argument or similar).
PeteDD wrote: |
---|
Now normally, these sorts of libraries are then globally available via the extern bringing them into the local namespace (right?). |
I'm a bit confused by your use of the word "library". Do you mean
variables?
extern just means it's a declaration and the definition is somewhere else (possibly in the same or a different translation unit).
It's only used for "global" variables that are defined outside of functions and classes.
PeteDD wrote: |
---|
For example, if I instantiated the OneWireSensor just in setup(), it would be available globally... |
No. It would be a local variables that is destroyed as soon as it goes out of scope (e.g. when the function ends).
PeteDD wrote: |
---|
..., so why not from initialize() which is called by setup() and especially after using the extern to bring it into the local namespace of this instance of AddData()? |
The order in which you call the functions doesn't affect what variables you can access.
extern OneWire oneWire;
just tells the compiler that there is a global variable of type OneWire named "oneWire" (in the same namespace* as you're currently in) so that you can use that variable in the code even though it has been defined somewhere else. In other words, it means a specific variable (inside a specific namespace*) and not just any variable with that name.
* Note that when I write "namespace" I do not mean a class or function scope. I mean an actual C++ namespace declared using the
namespace
keyword or the global namespace with no name that everything is inside by default.