0

I'm new to C++, and I'm trying to better organize my code, by moving methods and variables to header files so they can be better shared amongst .cpp files. So right now, I'm just trying to learn how best to use header files, but I seem unable to make even the simplest program.

Right now, I have two .cpp files and one .h file:

file1.cpp
file2.cpp
header.h

All I want to do is call a function that's defined in file2.cpp from main() inside of file1.cpp.

file1.cpp:

#include <iostream>
#include "header.h"
using namespace std;

void Log(const char* message) {
    cout << message << endl;
}

int main() {
    InitLog();
    Log("Hello World!");
}

file2.cpp:

#include <iostream>
#include "header.h"
using namespace std;

void InitLog()
{
    Log("Initializing Log");
}

header.h:

#pragma once

void InitLog();

void Log(const char* message);

I'm running on VScode. Every time I run file1.cpp, I get this error:

Undefined symbols for architecture x86_64:
  "InitLog()", referenced from:
      _main in file1-27a581.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

For whatever reason, I can't seem to get file1 to see the function definition in file2.

Is there something else I should be including in my header file? Do I need to compile things in a certain order? Please help!

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • You should put `extern` before function in header file. Next I would rename `header.h` to `file2.h`. At the end how compilation log/options looks like? – Andy Mar 16 '23 at 20:35
  • 1
    function declarations do not need `extern` in this situation – Remy Lebeau Mar 16 '23 at 20:35
  • 2
    What command are you using to compile this? If you're trying to compile and link the two files separately, then they won't be able to find each other's functions. The compile steps can happen separately (since the header makes them aware of each other's functions), but the two files need to be linked *together* so they actually know where to find those same functions. – Silvio Mayolo Mar 16 '23 at 20:37
  • I'm assuming changing the header name to "file2.h" doesn't actually affect the functionality? It's just standard practice? – isaacdejager Mar 16 '23 at 20:38
  • @SilvioMayolo I'm not running them from a command line. I'm using VSCode with just the suggested C/C++ extensions and then clicking the "Run C/C++ file" in the corner while on file1.cpp. I'm guessing that doesn't compile the other files – isaacdejager Mar 16 '23 at 20:40
  • @isaacdejager You can't "run" `file1.cpp` by itself. – Remy Lebeau Mar 16 '23 at 20:42

1 Answers1

0

The problem is not with the code that is shown, the code is fine.

The problem is with the linker instead. You need to compile both file1.cpp and file2.cpp, and then link the resulting object files together into the final .exe. The error you are seeing is from the linker, not the compiler. The linker is complaining that it can't find the implementation code for InitLog(), which file1.cpp is calling, which suggests that you are not linking to the object file that is produced by compiling file2.cpp.

You say that you are "running file1.cpp", but that is not good enough by itself, and is not how C++ works.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • What can I do in VSCode to have it compile multiple files without running them? – isaacdejager Mar 16 '23 at 20:45
  • See the link that I just closed your question as a duplicate of. – Remy Lebeau Mar 16 '23 at 20:48
  • 1
    Also the official VSCode documentation tells you that the default is to build only the active file into your executable and shows you the change you need to make to your tasks.json to build all cpp files in your folder here: [https://code.visualstudio.com/docs/cpp/config-mingw#_modifying-tasksjson](https://code.visualstudio.com/docs/cpp/config-mingw#_modifying-tasksjson) – drescherjm Mar 16 '23 at 22:09