Undefined Reference in C: Fix Main and Linker Errors

Two object-file modules separated by a missing connector illustrate an unresolved linker reference.

An undefined reference to main error typically indicates that the build made it to the linker, but the files being linked do not contain the main function that is required for a normal executable. First, see what you are constructing and which files are involved.

A missing entry point is seldom fixed by adding a header or changing an #include. The linker needs a function definition in the build.

Start with a complete program

Save this as main.c:

#include <stdio.h>

int main(void)
{
    puts("The program started.");
    return 0;
}

Build and run it in a Unix-like terminal:

gcc -std=c17 -Wall -Wextra -Wpedantic main.c -o app
./app

Expected output:

The program started.

The simple entry-point form is int main(void) for an ordinary hosted C program that doesn't use command-line arguments. Freestanding environments, including some embedded systems, use implementation-specific startup rules. See the C committee draft, section 5.1.2.

Check these causes first

Cause What to check Fix
No entry point Source defines helper functions only Add main if building an executable
Wrong capitalization Function is named Main or MAIN Use lowercase main
Declaration only File contains int main(void); Supply a function body
Wrong build inputs The file containing main is missing Add that source or object file to the link step
Unsaved editor changes Compiler reads an older file Save, then rebuild
Wrong target A library source is being built as an application Build an object or library instead

Look at the actual build command, not just the file that you see in your editor. Different targets can be compiled by IDEs and Makefiles than the one you think you are building.

Build a complete two-file program

An undefined reference in C can also mean a helper implementation was left out of the build. Try this complete example in a local terminal, using a separate directory from the earlier example. These commands do not assume that the online editor supports multiple files.

Save this as helper.c:

int add(int a, int b)
{
    return a + b;
}

Save this as main.c:

#include <stdio.h>

int add(int a, int b);

int main(void)
{
    printf("%d\n", add(2, 3));
    return 0;
}

Compile both files, then link their object files:

gcc -std=c17 -Wall -Wextra -Wpedantic -c helper.c -o helper.o
gcc -std=c17 -Wall -Wextra -Wpedantic -c main.c -o main.o
gcc main.o helper.o -o app
./app

The program prints 5. Leaving helper.o out of the link leaves add undefined. Building helper.c alone as an executable lacks main, while compiling it with -c is valid. The GCC build-stage documentation explains how -c stops before linking. Larger projects should keep shared declarations in a header included by both source files.

Check missing libraries and library order

A header supplies declarations; it does not supply a library's compiled implementation. When an undefined symbol belongs to a library, use that library's documented link options and put libraries after the objects that need them where your linker requires this order.

For example, some Unix-like toolchains require -lm when linking math-library calls:

gcc main.o -lm -o app

This command assumes main.o already exists and contains the program entry point. The requirement depends on the platform and actual generated calls; constant folding can eliminate some calls. Do not assume every program mentioning a math function must fail without -lm.

Undefined reference to another function

The same distinction applies if the error names add, calculate, or any function other than main: a declaration describes a function, while a definition provides its implementation.

This complete example contains both:

#include <stdio.h>

int add(int a, int b);

int main(void)
{
    printf("%d\n", add(2, 3));
    return 0;
}

int add(int a, int b)
{
    return a + b;
}

It prints 5. In a large project, the definition can be in a different source file, but the source file must be part of the build. If it is a library function, consult the documented order of the libraries and the linking command used by the library.

Why does it happen in a Makefile?

Check the recipe that builds your executable. It should have an object-file list that contains the object with main. Make sure that the default target is the application you want to create. A clean build can eliminate stale objects, but it cannot make up for an incomplete list of source files.

Is this a syntax error?

Typically no, it's a linker diagnostic. An implicit declaration error occurs earlier, when the compiler can't locate a valid declaration for a function call.

Should I add main to every C file?

No. A normal application has a single program entry point. Other functions are provided by helper files. If the main function is included in each source file, multiple-definition errors may result.

Paste the first example into the online C compiler to check the minimal program structure. Then compare it with the files and target in your failing build.

Related errors