1

I am new to Stack OF and C++. And I am following a tutorial by The Cherno wherein at 7:00 he is explaining how the linker would not try search for a function "Log" if the it is present in an unused static function. Which makes sense!

However upon me trying it. I don't get the same result and I do get a linker error.

Here is my code:

main.cpp

#include <iostream>

void Logger(const char*);

static int Multiplied(int a, int b, int c){
    Logger("Hello");
    return a * b;
}


int main(){

    //Logger("Hello World from Log function \n");
    //std::cout << Multiplied(3,4) << std::endl;
}

my source directory only has main.cpp

ls -lrth src
total 4,0K
-rw-rw-r-- 1 ubuntu18 ubuntu18 232 Feb 22 04:19 Main.cpp

The output directory has following file:

ubuntu18@ubuntu18:~/dev/HelloWorld$ ls -lrth CMakeFiles/HelloWorld.dir/src/
total 48K
-rw-rw-r-- 1 ubuntu18 ubuntu18 313 Feb 22 01:15 Main.cpp.i
-rw-rw-r-- 1 ubuntu18 ubuntu18 412 Feb 22 01:20 Math.cpp.i
-rw-rw-r-- 1 ubuntu18 ubuntu18 37K Feb 22 04:22 Main.cpp.o

Error:

ubuntu18@ubuntu18:~/dev/HelloWorld$ make all
/usr/bin/cmake -H/home/ubuntu18/dev/HelloWorld -B/home/ubuntu18/dev/HelloWorld --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/ubuntu18/dev/HelloWorld/CMakeFiles /home/ubuntu18/dev/HelloWorld/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/ubuntu18/dev/HelloWorld'
make -f CMakeFiles/HelloWorld.dir/build.make CMakeFiles/HelloWorld.dir/depend
make[2]: Entering directory '/home/ubuntu18/dev/HelloWorld'
cd /home/ubuntu18/dev/HelloWorld && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/ubuntu18/dev/HelloWorld /home/ubuntu18/dev/HelloWorld /home/ubuntu18/dev/HelloWorld /home/ubuntu18/dev/HelloWorld /home/ubuntu18/dev/HelloWorld/CMakeFiles/HelloWorld.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/ubuntu18/dev/HelloWorld'
make -f CMakeFiles/HelloWorld.dir/build.make CMakeFiles/HelloWorld.dir/build
make[2]: Entering directory '/home/ubuntu18/dev/HelloWorld'
[ 50%] Linking CXX executable HelloWorld
/usr/bin/cmake -E cmake_link_script CMakeFiles/HelloWorld.dir/link.txt --verbose=1
/usr/bin/c++   -Wall -g   CMakeFiles/HelloWorld.dir/src/Main.cpp.o  -o HelloWorld 
CMakeFiles/HelloWorld.dir/src/Main.cpp.o: In function `Multiplied(int, int, int)':
/home/ubuntu18/dev/HelloWorld/src/Main.cpp:5: undefined reference to `Logger(char const*)'
collect2: error: ld returned 1 exit status
CMakeFiles/HelloWorld.dir/build.make:97: recipe for target 'HelloWorld' failed
make[2]: *** [HelloWorld] Error 1
make[2]: Leaving directory '/home/ubuntu18/dev/HelloWorld'
CMakeFiles/Makefile2:70: recipe for target 'CMakeFiles/HelloWorld.dir/all' failed
make[1]: *** [CMakeFiles/HelloWorld.dir/all] Error 2
make[1]: Leaving directory '/home/ubuntu18/dev/HelloWorld'
Makefile:86: recipe for target 'all' failed
make: *** [all] Error 2

I would love to know the explanation. Why is it so?

Edit: Updated video timestamp and, Here is the compiler information in my CMake

set(CMAKE_C_COMPILER_ID "GNU")
set(CMAKE_C_COMPILER_VERSION "7.5.0")

NOTE: I would appreciate if you could watch the video tagged in the first line from 7:00 to understand the problem better. Thanks!

Adeeb
  • 11
  • 2
  • 1
    Logger is defined and not implemented anywhere. – Omid CompSCI Feb 22 '22 at 03:47
  • @OmidCompSCI If you refer to the video; then probably you would understand better. The linker should not throw any error as the function it is being called by is not invoked in the main function and is static! – Adeeb Feb 22 '22 at 04:13
  • The function is _not_ being called. It is being _declared_. It must be defined (implemented) as well. – jkb Feb 22 '22 at 04:19
  • The question is: since Multiplied is not called from main, it makes no sense for the linker to search for definition (implementation) of Multiplied (and thus Logger). Is that right @Adeeb? – kiner_shah Feb 22 '22 at 04:20
  • Also, please include which compiler you are using and its version. – kiner_shah Feb 22 '22 at 04:21
  • It's not `Multiplied` that the linker is complaining about. It is `Logger`, which is called from within `Multiplied`. – jkb Feb 22 '22 at 04:22
  • @kiner_shah Exactly! I have updated the compiler details in the edit. – Adeeb Feb 22 '22 at 04:32
  • 1
    The video is wrong. The function `Logger` is odr-used. If a definition is not available, then you have an ODR violation, but the compiler is not required to diagnose such an error: "[Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; **no diagnostic required**.](https://timsong-cpp.github.io/cppwp/basic.def.odr#10)" In other words, the linker is allowed to raise an error, but it is also allowed to ignore the error (and behave in an undefined way). Both behaviors are legal. – Raymond Chen Feb 22 '22 at 04:34
  • @RaymondChen thanks for the link and pointing out that explanation in the video is wrong. For a moment I thought that guy was infallible. Honestly your explanation went over my head. However I got the point that the both ways is possible. – Adeeb Feb 22 '22 at 04:47

1 Answers1

0
#include <iostream>

void Logger(const char* std_output)
{
    std::cout << std_output << std::endl;
}

static int Multiplied(int a, int b, int c){
    Logger("Hello");
    return a * b;
}


int main(){

    Logger("Hello World from Log function \n");
    std::cout << Multiplied(3,4,5) << std::endl;
}

A few things to note:

  1. You defined Logger but did not implement. The definition will not magically be revealed anywhere, unless implemented or coming from another header where it is implemented

  2. You were passing 2 parameters to Multiplied I added a 3rd dummy. You don't utilize int c, so i suggest removing it

  3. Updated Logger to be implemented to just output to std output. You can change it to be as sophisticated as you'd like.

  4. This compiles as is now.

Omid CompSCI
  • 1,861
  • 3
  • 17
  • 29
  • I think you did not understand the question. I know how to make it work, But I just wanted to know why I was recieving the linker error, as opposed to the explaination in the video. :) – Adeeb Feb 22 '22 at 04:49