Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

undefined reference to 'main' appears during the linking stage. Your compiler may have successfully converted the source code into object files, but the final executable link cannot find the program entry point it needs.

In most cases, the fix is one of three things: define a valid main, add the object or source file containing it to the final link command, or change the target because you are actually building a library, DLL, plugin, or another non-executable artifact.

What the error actually means

A C or C++ build normally has two distinct stages:

  1. Compilation: each source file is checked and converted into an object file such as main.o or main.obj.
  2. Linking: the object files and libraries are combined into an executable.

undefined reference to 'main' is a linker error. It means the linker is creating an executable but cannot resolve the required entry-point symbol in the files supplied to that link operation.

Having a file named main.c or main.cpp in the project directory is not enough. That file must be compiled and its resulting object file must appear in the executable’s final link inputs.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a valid entry point

Portable C

A minimal C program can use either of these forms:

int main(void) { return 0; }

int main(int argc, char *argv[]) { return 0; }

Microsoft C also supports this Microsoft-specific form:

int main(int argc, char *argv[], char *envp[]) { return 0; }

Use int main for portable code. Although Microsoft documents void main() as a compiler extension, it is not the portable C or C++ form.

Portable C++

int main() { return 0; }

int main(int argc, char* argv[]) { return 0; }

Check spelling, capitalization, return type, and parameters. Main, MAIN, and an incompatible overload are not substitutes for the expected entry point. In Microsoft C, main must not be declared static or inline.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Fix the GCC command

When compiling and linking in one command, include the file that defines main.

One C file

gcc main.c -o app

Several C files

gcc main.c helper.c math.c -o app

One C++ file

g++ main.cpp -o app

Several C++ files

g++ main.cpp helper.cpp math.cpp -o app

This command is a typical cause of the error:

gcc helper.c -o app

If helper.c contains functions but no main, GCC is being asked to produce an executable from a file that has no entry point. Add the source file containing main:

gcc helper.c main.c -o app

The filename is irrelevant. A function named main in program.c works just as well:

gcc program.c helper.c -o app

Check the final link line when using object files

Separate compilation is valid, but the final command must contain the object that defines main:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

gcc -c main.c; gcc -c helper.c; gcc main.o helper.o -o app

For C++:

g++ -c main.cpp; g++ -c helper.cpp; g++ main.o helper.o -o app

Running only the commands with -c does not attempt to create an executable, so it cannot produce a missing-main linker error. The problem occurs in the final link command.

For example, this omits the entry-point object:

gcc helper.o -o app

Correct it by adding main.o:

gcc main.o helper.o -o app

With a build system, inspect the complete verbose link command and verify that the expected .o or .obj file is present. The source file may compile successfully while being excluded from the target.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use g++ for the normal C++ link

Use gcc for C and g++ for C++. The important difference is not usually the presence of main; it is the runtime and libraries linked after compilation.

g++ automatically links the C++ standard library when it performs the final link. If you intentionally link C++ object files with gcc, you may instead see unresolved symbols from the C++ runtime or standard library. The normal correction is:

g++ main.o helper.o -o app

Changing from gcc to g++ is not a universal fix for undefined reference to 'main'. If main.o is absent, the correct C++ driver still cannot find main.

Fix a CMake target that omits the entry-point file

CMake associates source files with individual targets. Adding a file to an IDE or placing it in the project directory does not automatically add it to an executable target.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

This target can fail because it contains only a helper file:

add_executable(app helper.cpp)

List the source containing main:

add_executable(app main.cpp helper.cpp)

After changing CMakeLists.txt, regenerate or rebuild the target. A verbose build helps you see the actual compiler and linker commands:

cmake --build . --verbose

Look for the link command for app and check that the object generated from main.cpp appears on it.

A library target does not normally need an application-style main. If you accidentally configure a library’s implementation files as an executable, or try to build a test/plugin component as a standalone executable, correct the target type instead of adding a dummy function.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check conditional compilation

The source may visibly contain main while the active build configuration removes it:

#ifdef BUILD_EXECUTABLE int main(void) { return 0; } #endif

If BUILD_EXECUTABLE is not defined, the object file contains no main. Check the compiler’s preprocessor definitions and the configuration used for the failing target. In GCC, a build might need:

gcc -DBUILD_EXECUTABLE main.c -o app

Do not assume the Debug and Release configurations use the same defines or source lists.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Visual Studio and MSVC

MSVC reports the equivalent problem as:

LINK : fatal error LNK1561: entry point must be defined

For a normal console executable, MSVC expects main or wmain. A Windows-subsystem executable uses WinMain or wWinMain. A DLL uses DllMain when applicable and does not require an application-style main.

Target Typical entry point
Console executable main or wmain
Windows-subsystem executable WinMain or wWinMain
DLL DllMain

Check these items in the Visual Studio project:

  1. Open Project Properties.
  2. Select Configuration Properties → General and confirm that the project type is appropriate.
  3. For a console program, check Linker → System → SubSystem and select Console.
  4. Confirm that the source file defining the entry point belongs to the project and is not excluded from the active configuration.
  5. Check the function’s spelling and signature.

If the project is intentionally a Windows-subsystem application, define WinMain or wWinMain rather than ordinary main.

Do not use an entry-point override as the first fix

Visual Studio exposes an entry-point override at:

Project Properties → Configuration Properties → Linker → Advanced → Entry Point

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value

The linker option is:

/ENTRY:function

GNU linkers also support explicit entry selection:

gcc -Wl,-e,main main.o -o app

These options only tell the linker which symbol to treat as the entry point. They do not add a missing object file, repair an incorrect function signature, select the correct subsystem, or link the C++ runtime. Overriding the MSVC entry point can also bypass C runtime initialization and C++ static-object constructors. Let the compiler driver and default runtime startup code choose the entry point unless you are implementing a specialized startup sequence.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Other build types that should not have main

Not every C or C++ compilation should produce a standalone executable:

  • A static or shared library exports functions for another program.
  • A DLL has a DLL-specific initialization model.
  • A plugin is loaded by a host application.
  • A test fixture may be launched by a test runner that supplies its own entry point.
  • Firmware and operating-system components may use startup symbols defined by a linker script or platform runtime.

If one of these is your intended artifact, inspect the build target rather than adding an arbitrary main. If it is supposed to be an executable, make sure the target includes exactly one valid entry-point definition.

A quick diagnostic checklist

  1. Read the complete error and identify the toolchain: GCC, Clang, or MSVC.
  2. Confirm that the target is meant to be an executable.
  3. Find the actual definition of main, wmain, WinMain, or wWinMain.
  4. Check its spelling, capitalization, return type, and parameters.
  5. Check conditional compilation around the definition.
  6. For GCC, use gcc for C and g++ for C++.
  7. Inspect the final verbose link command.
  8. Verify that the object file containing the entry point is on that command.
  9. For CMake, add the file to add_executable and rebuild the generated files.
  10. For Visual Studio, verify the subsystem and active-configuration file settings.

Common incorrect fixes

Claim What is actually true
Every source file needs main. Only an executable target needs an application entry point. Helpers and libraries normally do not.
The file must be named main.c. The linker needs the symbol, not a particular filename.
Including <stdio.h> fixes it. Headers declare APIs; they do not normally define your program’s entry point.
void main() is the portable answer. Use int main in portable C and C++.
-e main always fixes the error. It only changes entry-symbol selection and does not supply omitted code or runtime initialization.
Switching from gcc to g++ always fixes it. g++ is correct for normal C++ linking, but a missing main object remains missing.

FAQ

Is “undefined reference to main” a compiler error?

No. It is normally a linker-stage error. Compilation may have succeeded; the final executable link could not find the required entry-point symbol.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Does the file have to be called main.c or main.cpp?

No. Any source filename works if it defines a valid entry point and is included in the executable target’s final link inputs.

Why does gcc helper.c -o app fail?

That command asks GCC to create an executable from a file that has no main function. Include the source or object file containing main, or build helper.c as part of a library instead.

Can a C++ program use gcc?

It can, but g++ is the normal driver for the final C++ link because it automatically supplies libstdc++. Using gcc for C++ more commonly causes missing C++ runtime symbols; it does not by itself explain a missing main.

What should a DLL use instead of main?

A DLL does not use the normal application entry-point model. Its initialization entry point is DllMain when applicable. Configure the target as a DLL rather than forcing an executable entry point.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I set /ENTRY:main in Visual Studio?

Usually no. First fix the project type, subsystem, source membership, signature, or link inputs. An entry-point override can bypass normal C runtime initialization and C++ static-object construction.

The Bottom Line

Find the final link command and verify that it includes an object file containing a valid entry point. For GCC, link all required files with gcc for C or g++ for C++; for CMake and Visual Studio, correct the executable target and its active configuration. If the target is a library, DLL, plugin, or test component, it may correctly have no ordinary main.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.