The Compile–Link–Load Toolchain

linker errors (undefined reference, multiple definition)

There is a moment of confusion many beginners hit: the compiler said nothing was wrong, yet the build still failed, with a strange message mentioning no line number in your code. That is almost always a linker error. It comes from the very last stage, after every file has compiled fine on its own, when the linker tries to wire the files together and finds that the names do not match up. Because the problem is about how files connect, not about any single line, the messages look different from compiler errors.

The two you will meet by far the most are mirror images of each other. 'Undefined reference to add' means some file uses the name add, but no object file or library actually defines it: the linker searched everywhere and found a wanted symbol with no provider. Typical causes are forgetting to compile or link the .c file that defines it, a misspelled name, a mismatched signature in C++ due to name mangling, or forgetting to link a library. 'Multiple definition of count' means the opposite: the name count is defined in two places at once, so the linker cannot pick one. The classic cause is putting a real definition (not just a declaration) in a header that several files include, so each one bakes in its own copy.

The cure follows from the cause. For 'undefined reference', check that the defining source file is actually part of the build and that names and signatures match, and add any missing library to the link line. For 'multiple definition', move definitions out of headers into a single .c file and leave only declarations (often with extern) in the header, protected by an include guard. The deeper lesson is that 'it compiles' is not the same as 'it builds': passing the compiler only proves each file is internally consistent, while the linker checks that the files agree with each other.

$ gcc main.c -o app # forgot to include utils.c! /usr/bin/ld: main.o: in function `main': main.c:(.text+0x12): undefined reference to `add' # fix: $ gcc main.c utils.c -o app

A clean compile still fails to link because the file defining add was left out of the build.

Linker errors usually carry no source line number because the problem is between files, not within one; passing the compiler proves nothing about whether the pieces will link together.

Also called
link-time errorunresolved external連結錯誤