-1

Let me explain what I want to understand, recently I see these videos from youtube about how the compiler and the linker work.

How C++ works:

https://www.youtube.com/watch?v=SfGuIVzE_Os&list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb&index=5

How C++ compiler works:

https://www.youtube.com/watch?v=3tIqpEmWMLI&list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb&index=6

How C++ linker works:

https://www.youtube.com/watch?v=H4s55GgAg0I&list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb&index=7

In those videos, it is explained what happens when you have functions with the same declaration and definition, but just have examples with static to static functions (that solves the linking error since each function is seen different) and non-static to non-static functions (which gives a linking error since the linker do not know what function are you calling).

However, those videos are just extra information I will explain my doubt. Suppose we want to have to functions with the same declaration but different definition for some reason and we make the next code.

Math.cpp file:

int Multiply(int a, int b) {
    return 0;
}

Main.cpp file:

#include <iostream>

int Multiply(int, int);

static int Multiply(int a, int b) {
    int result = a * b;
    return result;
}

int main() {

    std::cout << Multiply(5, 2) << std::endl;
    std::cin.get();
}

Running this code, the static Multiply function is called.

How the linker knows what function are you calling on main function?

and with the given code:

How can I call the Multiply function that is on the Math.cpp file from main function having the static version?

  • 1
    What compiler are you using? This code doesn't compile with g++. – NathanOliver Sep 24 '20 at 20:08
  • 1
    Here's a simplification. All functions have a visibility, public or not public. The not public or `static` functions are only visible to functions in the same translation unit (source file). Functions outside that translation unit cannot access the static functions. Otherwise the function can be accessed outside of the translation unit. – Thomas Matthews Sep 24 '20 at 20:10
  • Can you change the name of the function in the `main` file? – Thomas Matthews Sep 24 '20 at 20:11
  • You could use namespaces to help differentiate the functions. – Thomas Matthews Sep 24 '20 at 20:12
  • NathanOliver, I'm using Visual Studio, but I do not know what compiler it has by default. – Josael Perez Sep 24 '20 at 20:21
  • Thomas Matthews, what I want to know is why the linker chose the static int Multiply function on the Main.cpp file instead of the multiply version on Math.cpp – Josael Perez Sep 24 '20 at 20:23
  • Actually, on Main.cpp file you have access to both multiply functions, which are different for the linker since one of them is static, but the linker runs the static version, if I delete it it runs the multiply function on the Math.cpp file. So what is the logic to the linker to decide what function should be ran? – Josael Perez Sep 24 '20 at 20:25
  • 3
    Don't learn C++ from YouTube videos. Get a [good book](https://stackoverflow.com/q/388242/5910058) (or two) instead. And *read* them. – Jesper Juhl Sep 24 '20 at 20:32
  • 2
    The linker did not "choose" anything. There was nothing to choose from. The linker gets involved to resolve external references. There was no external reference to result. `main.cpp`'s function call is not a call to an unresolved symbol, but to the static function in the same `.cpp` file. The End. P.S. You will not learn C++ from YouTube videos. Only from a [good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Sam Varshavchik Sep 24 '20 at 21:18
  • Sam, but I wonder why the main.cpp's function call is calling the static function instead of the Math.cpp one when both are acessible from Main.cpp file. If I delete the static one and run it, the main's function call now calls the Math.cpp multiply function, but if I leave it, the static one is called. – Josael Perez Sep 24 '20 at 21:30
  • Usually, when you have same functions there is a linker error that say the function is already defined on some .obj file. If you put both functions as static, the call will have access just to the function in the same file (that makes sense). But if you have same function declaration (one static and another non-static), there is no linking error what means both functions are different for the linker, but on code you can call them same way, and the linker runs the static one (if it exists) or the external reference (if the static do not exists) and I wonder what logic the linker follows – Josael Perez Sep 24 '20 at 21:35
  • 1
    The compiler knows it doesn't bother the linker with having to figure it out. Hopefully intuitive: it *must* work that way. `static` means "don't tell the linker about this function". – Hans Passant Sep 24 '20 at 22:43

1 Answers1

1

int multiply(int, int); doesn’t say “there’s a function defined in some other file named multiply. It says “there’s a function defined somewhere named multiply“. That’s enough information to allow subsequent code to call multiply. When the compiler then sees the definition of multiply it says “aha, there it is! And it’s marked static, so I’m not supposed to make it visible outside this translation unit”. Then it sees the call to multiply and says “I know that one because I saw it earlier”. Done and done.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • But the question here is why the linker is using the static function if I have 2 accessible functions that I can call with "Multiply(5,2)" for instance? If I leave the static one written, the linker links my multiply call (on the main function) with the static one, but if I delete this static one, the linker links the call to the multiply function on the Math.cpp file – Josael Perez Sep 24 '20 at 22:36
  • That means the main function have access to both functions which can be called same way - Multiply(int, int) - but the linker links the static to be used before the other one so I wonder how the linker logic to link these calls to functions works (first question on bold) – Josael Perez Sep 24 '20 at 22:41
  • 1
    @JosaelPerez — I didn’t mention the linker because it’s not involved here. The **compiler** saw the definition, and that’s all it needed. – Pete Becker Sep 24 '20 at 22:41
  • But I have two definitions, and one of them is being used before the another and I wonder why. The compiler is just responsible to see (in this case) if I have a definition of the function I'm calling, but it do not attach (as far as I know) the calling with a particular function definition (you could compile with just a declaration of the function and for the compiler it will be okay). The linker is responsible to see your functions and attach those calls to one of them. – Josael Perez Sep 24 '20 at 22:53
  • Writting - Multiply(5,2) - I could call either the static int Multiply(int, int), or if I removed it, the int Multiply(int, int), which means main function can access both of them when both exists, but I could not find (even in books) why one is linked before the other one. I don't know if it is something like "priority" or something else – Josael Perez Sep 24 '20 at 22:57
  • @JosaelPerez The compiler calls the definition it can see. That's what it's supposed to do. It's not even aware of the other defnition when compiling this one, and the linker isn't aware of this definition. – user207421 Sep 24 '20 at 23:18
  • But the compiler does not check about definitions, I could get rid of both multiply functions and leave just a declaration and it will compile correctly, of course if I build the project (compiling and linking) there will be a linking error since the linker could not find the definition. In addition, the linker knows about every definition on each translation unit and wire them to where they are called – Josael Perez Sep 24 '20 at 23:26