gcc: Undefined Reference to WinMain (Fix on Windows) - DEV Community

DEV Community

Yunus Emre Güzel
Yunus Emre Güzel

Posted on Edited on Originally published at blog.emreguzel.ca

gcc: Undefined Reference to WinMain (Fix on Windows)

Cause 4: Two Files Both Have a main

// a.c
int main(void) { return 0; }

// b.c
int main(void) { return 1; }
Enter fullscreen mode Exit fullscreen mode

You get one main per program. Put it in two files and the linker bails out with a different message:

two_b.c:(.text+0x0): multiple definition of `main'; two_a.c:(.text+0x0): first defined here
Enter fullscreen mode Exit fullscreen mode

It usually happens by accident. Your editor's build task compiles every .c file in the folder, so two experiments side by side clash. The task in my own repo does exactly that (gcc ${fileDirname}\*.c). A task that builds only the open file gives you the opposite problem, the one in the section above. So check what your build task really runs. Then keep one program per folder, or call gcc yourself with the exact files you want.

How to Read a Linker Message

Take a message like main.c:(.text+0xe3): undefined reference to `tasklist_init’. The file name tells you which file asked for the function, and (.text+0xe3) is a position inside the compiled code that you can ignore. The part that matters is the name after undefined reference to. The last line, collect2.exe: error: ld returned 1 exit status, only says that the linker failed, so the useful information is always in the lines above it. Scroll up and read the first undefined reference or multiple definition.

Seeing lots of undefined references for different functions? Check whether they all live in one file. I compiled only main.c of the task manager from How to Build Real-World Projects in C. One missing tasks.c gave me a separate error for every function in it. That's one missing file, not a pile of bugs.

Compile Error or Link Error?

The wording tells you which step broke, and that tells you where to look:

Message Step Look at
implicit declaration of function Compiler Missing #include, a typo, or a function used before it is declared. See C Error: Implicit Declaration of Function.
undefined reference to a function you wrote Linker A .c file missing from the gcc command
undefined reference to WinMain (or main) Linker No main, or main misspelled
multiple definition of Linker The same function defined in two files

The Short Answer

Gcc on Windows says undefined reference to 'WinMain'? Then the linker can't find a function called main in your program. Check the spelling and the capital letters. Make sure main has a body. Make sure the file that holds it is in your gcc command. Why does the message say WinMain? Because that's the entry point Windows programs fall back to when main is missing.

C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/16.2.0/../../../../lib/libmingw32.a(lib64_libmingw32_a-crtexewin.o):crtexewin.c:(.text.startup+0xc6): undefined reference to `WinMain'
collect2.exe: error: ld returned 1 exit status
Enter fullscreen mode Exit fullscreen mode

Don't worry about the long path on the first line. It's just where gcc keeps its own startup code. Look at the end: undefined reference to `WinMain'. Everything below shows the causes I could reproduce with gcc 16.2 from MSYS2 on Windows, in the order you are most likely to meet them. If you use a different compiler setup, the wording may differ (some setups name main instead), but the causes are the same.

Why You See WinMain and Not main

Building a C program takes two steps. First the compiler turns each .c file into an object file. Then the linker glues the object files into a program. Every program needs one entry point, which is the function the operating system starts. With MinGW gcc on Windows, a program can start from main or from the Windows-style WinMain. Define neither and the linker names WinMain. That's what I got every time main was missing or misnamed. I didn't dig into gcc's startup code to confirm why, so read the name as a sign that no entry point was found.

This also tells you something handy. The error comes from the linker (ld), not the compiler. So your syntax is fine. The file even compiles on its own if you stop before linking:

gcc -c nomain.c -o nomain.o
Enter fullscreen mode Exit fullscreen mode

That command works and prints nothing. The error shows up only when gcc tries to build a program from it.

Cause 1: The File Has No main at All

You'll hit this when you build a file that holds only helper functions. Or when you started a file and forgot the entry point:

#include <stdio.h>

void hello(void) {
    printf("hello\n");
}
Enter fullscreen mode Exit fullscreen mode

Build it with gcc nomain.c -o nomain.exe and you get the WinMain error above. Add a main that calls the function and you're done:

#include <stdio.h>

void hello(void) {
    printf("hello\n");
}

int main(void) {
    hello();
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

Cause 2: main Is Misspelled or Has the Wrong Capital

C cares about case. Main and mian aren't main, they're other functions. Both of these gave me the same WinMain error on my machine:

#include <stdio.h>

int mian(void) {      /* typo: mian */
    printf("hello\n");
    return 0;
}
Enter fullscreen mode Exit fullscreen mode
#include <stdio.h>

int Main(void) {      /* capital M */
    printf("hello\n");
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

The compiler stays quiet, since mian and Main are fine names for a function. Only the linker notices that nothing is called main. Rename it to a lowercase main. It builds and prints hello.

Cause 3: You Are Building the Wrong File

A project with several files keeps main in just one of them. Name only a helper file in your command and the linker has no entry point to find. This helper file has no main:

#include <stdio.h>

void greet(void) {
    printf("hi from helper\n");
}
Enter fullscreen mode Exit fullscreen mode

Run gcc helper.c -o helper.exe and you get the WinMain message. Build the file that has main instead, and name it in the command, as the next section shows.

Related Error: undefined reference to Your Own Function

Sometimes the name in the message is one of your own functions, not WinMain. That's the opposite problem. main is there, but a function it calls lives in a file you never gave to gcc. Here app.c calls greet, which is defined in helper.c:

void greet(void);

int main(void) {
    greet();
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

Build only app.c and it fails with undefined reference to `greet'. Give gcc both files and it works:

gcc app.c helper.c -o app.exe
./app.exe
Enter fullscreen mode Exit fullscreen mode
hi from helper
Enter fullscreen mode Exit fullscreen mode

Don't mix this up with the implicit declaration of function error. That one comes from the compiler, when it hasn't seen a declaration. Here the declaration is fine. The linker just can't find the function body.

How to Tell Which Cause You Have

  • Look at the name after undefined reference to. WinMain means there's no usable main. Any other name means a function body is missing from the build.

  • Search your file for main. Is it lowercase? Spelled right? Does it have a body in braces?

  • Check your gcc command. Does it name every .c file the program needs, including the one with main?

  • Building from an editor? Make sure it compiles the file you're looking at, not an older one.

Build With Warnings On

Run gcc -Wall -Wextra every time, like in the garbage value guide. It won't flag a misspelled main. It does catch plenty of other mistakes before the linker sees them. Does your program build now but skip input? Read why your C program skips the second scanf. Just starting out? The Introduction to C programming guide covers main and compiling from the beginning.

The Checklist

  • Your program has exactly one function named main, all lowercase, with a body.

  • Your gcc command lists every .c file the program needs.

  • The file with main is one of them.

  • WinMain in the error means the entry point is missing. Any other name means a function body is missing.

  • The linker raises this error, so fix the build and the names. Your syntax is fine.

The linker just can't find a place to start. Spell main right, build the right files together, and the error is gone.

Download the code: broken and fixed versions of these cases are on GitHub in C-Programing/Troubleshooting/undefined-reference. You get no main, a misspelled main, a two-file project, and two main functions. Compile one file at a time. For the two-file example, use gcc main.c greet.c. Builds fine but crashes? See Segmentation Fault in C: Find the Exact Line.


Originally published on my blog. I post new C, Python and AI-agent guides there regularly.

Top comments (0)