3

I'm quite new to programming in general and more specifically to c++. I've made a program using the following files:

my.h

extern int foo;
void print_foo();

my.cpp

#include <iostream>
#include "my.h"


void print_foo(){
    std::cout << "foo = " << foo <<std::endl;

}

use.cpp

#include "my.h"

int main(){
    int foo = 7;
    print_foo();
}

When i try to compile it I get the error message 'undefined reference to `foo'', but when i define foo outside of my main() function like below, it works just fine. Why is that?

use.cpp

#include "my.h"

int foo;

int main(){
    foo = 7;
    print_foo();
}
  • 6
    `int foo = 7;` is a variable local to `main`. It is not the same thing as the declared `extern` variable of the same name, which is never defined. Read about lexical scope, declarations, and definitions in [a good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282). – molbdnilo May 23 '23 at 09:41
  • 1
    When you declare a variable inside a function (in your case `foo` inside `main`), this variable cannot be accessed outside the scope of your function. It works in the second case because `foo` is declared in the global scope. – M. Yousfi May 23 '23 at 09:42
  • @M.Yousfi `extern int foo;` is a global too – 463035818_is_not_an_ai May 23 '23 at 09:46
  • 1
    @463035818_is_not_a_number I agree, but with just `extern int foo;` the variable foo is declared but not defined. – M. Yousfi May 23 '23 at 09:49
  • 1
    @463035818_is_not_a_number No it isn't. It is a *declaration* of a global, that has to be defined somewhere, and the one in `main()` doesn't count. – user207421 May 23 '23 at 09:59
  • @user207421 I was refering to their comment " It works in the second case because foo is declared in the global scope. " thats not the reason the second works and the firs not. `foo` is declared as global in the first as well. As you say the crucial difference is the definition – 463035818_is_not_an_ai May 23 '23 at 10:11
  • 2
    Why should a new programmer start with `extern` or `static` objects? They're big **"no no"**'s. Use cases are limited to specific cases, and good implementations do not use them in API. – Red.Wave May 23 '23 at 10:16

3 Answers3

3

When i try to compile it I get the error message 'undefined reference to `foo''

Because when you define foo inside main, it is local to the main function. But the foo that you use inside print_foo is a global foo which you've not defined(globally).


Basically, extern int foo;(in your program) declares a global variable named foo and the foo used inside print_foo is the globally declared foo which you never define.

but when i define foo outside of my main() function like below, it works just fine

In this case, since you've defined foo globally and since foo inside print_foo refers to the globally declared foo, the program works as expected since a global definition of foo is available in this case.

Jason
  • 36,170
  • 5
  • 26
  • 60
2

The short answer to your question is that scope matters. For example, every foo in this program is a variable in their own right, and all of them refer to different things/values/memory locations/whatever you want to call it:

int foo;

void stuff(int foo) { ... }

void thing() {
  int foo;
}

namespace bla {
  int foo;
}

I am not even sure where to start the long answer, and so will instead refer you to The Definitive C++ Book Guide and List

Frodyne
  • 3,547
  • 6
  • 16
2

As you have discovered, you cannot do this because extern-variables and function-local variables are entirely different things.

And you should be able to infer this by yourself, because:

  • When you declare a variable inside a function, that variable is, of course, only visible within the scope of that function, and invisible by anything outside of that function.

  • When you declare a variable in the global scope, that variable is, of course, visible by anything and everything.

Therefore, if it was in some magic way possible to make that function-local variable definition satisfy the extern variable definition, you would somehow be making a function-local variable visible in the global scope, which does not make sense, the whole purpose of the language is to prevent things like that from happening, is physically impossible due to global variables living in the data segment whereas function-local variables living on the stack, etc. etc.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142