This code compiles, but no surprises, it fails while linking (no main found):
Listing 1:
void main();
Link error: mingwliblibmingw32.a(main.o):main.c:(.text+0x106) undefined reference to _WinMain@16′
But, the code below compiles and links fine, with a warning:
Listing 2:
void (*main)();
warning: ‘main’ is usually a function
Questions:
-
In listing 1, linker should have
complained for missing «main». Why
is it looking for _WinMain@16? -
The executable generated from
listing 2 simply crashes. What is
the reason?
Thanks for your time.
asked Feb 12, 2010 at 14:23
1
True, main
doesn’t need to be a function. This has been exploited in some obfuscated programs that contain binary program code in an array called main
.
The return type of main() must be int
(not void
). If the linker is looking for WinMain
, it thinks that you have a GUI application.
answered Feb 12, 2010 at 14:27
TronicTronic
10.1k2 gold badges41 silver badges53 bronze badges
0
In most C compilation systems, there is no type information associated with symbols that are linked. You could declare main as e.g.:
char main[10];
and the linker would be perfectly happy. As you noted, the program would probably crash, uless you cleverly initialized the contents of the array.
Your first example doesn’t define main, it just declares it, hence the linker error.
The second example defines main, but incorrectly.
answered Feb 12, 2010 at 14:30
4
Case 1. is Windows-specific — the compiler probably generates _WinMain
symbol when main
is properly defined.
Case 2. — you have a pointer, but as static variable it’s initialized to zero, thus the crash.
answered Feb 12, 2010 at 14:30
Nikolai FetissovNikolai Fetissov
81.3k11 gold badges109 silver badges169 bronze badges
2
On Windows platforms the program’s main unit is WinMain if you don’t set the program up as a console app. The «@16» means it is expecting 16 bytes of parameters. So the linker would be quite happy with you as long as you give it a function named WinMain with 16 bytes of parameters.
If you wanted a console app, this is your indication that you messed something up.
answered Feb 12, 2010 at 15:27
T.E.D.T.E.D.
43.5k10 gold badges71 silver badges135 bronze badges
You declared a pointer-to-function named main, and the linker warned you that this wouldn’t work.
The _WinMain message has to do with how Windows programs work. Below the level of the C runtime, a Windows executable has a WinMain.
answered Feb 12, 2010 at 14:31
bmarguliesbmargulies
96.6k39 gold badges182 silver badges308 bronze badges
In listing 1, you are saying «There’s a main() defined elsewhere in my code — I promise!». Which is why it compiles. But you are lying there, which is why the link fails. The reason you get the missing WinMain16 error, is because the standard libraries (for Microsoft compiler) contain a definition for main(), which calls WinMain(). In a Win32 program, you’d define WinMain() and the linker would use the library version of main() to call WinMain().
In Listing 2, you have a symbol called main defined, so both the compiler & the linker are happy, but the startup code will try to call the function that’s at location «main», and discover that there’s really not a function there, and crash.
answered Feb 12, 2010 at 14:38
James CurranJames Curran
101k36 gold badges180 silver badges257 bronze badges
2
1.) An (compiler/platform) dependent function is called before code in main is executed and hence your behavior(_init
in case of linux/glibc).
2) The code crash in 2nd case is justified as the system is unable to access the contents of the symbol main
as a function which actually is a function pointer pointing to arbitrary location.
answered Feb 12, 2010 at 14:49
Перейти к содержанию
На чтение 1 мин Обновлено 16.01.2023
Linker error the program has no main function
icedev |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Зарегистрирован: Сб окт 22, 2011 20:30:26 |
|
Problem with Compiling
Ok. So I’ve tried almost everything suggested on the net about this problem. I’ve tried using Netbeans, Eclipse, and a few other programs, but nothing works. I keep coming back to Visual Studio and I still can’t get this to work.
I’ve tried changing the linker to Windows and it doesn’t work. I get this:
SVCRTD.lib(wcrtexew.obj) : error LNK2019: unresolved external symbol _wWinMain@16 referenced in function ___tmainCRTStartup
Then I change to console and get this:
MSVCRTD.lib(wcrtexew.obj) : error LNK2019: unresolved external symbol _wWinMain@16 referenced in function ___tmainCRTStartup
(I know it’s the same thing, but nothing works)
I’ve had all kinds of weird errors and nothing seems to be working correctly. Any help would be appreciated.
My teacher says the code is right, but I can’t seem to get it to compile correctly in any program. I got Minigw installed as well.
/************************************************************/
/* Power Loss in a Transmission Line */
/************************************************************/
/* Defined constants: */
/* POWER – 500 kW */
/* RESIST – 0.05 ohms/mile */
/* Computed Variables: */
/* i – 500/100 and 500/200 */
/* R – 0.05 * 20, 30, …, 100 */
/* ploss – (i * i) * R */
/* Output Variables: */
/* ploss – power loss of current with resistance */
/* volt – volts */
/* mile – distance power traveled */
/************************************************************/
#include <stdio.h>
#include <math.h>
int main ( )
{
const int POWER= 500;
const float RESIST= 0.05;
int volt, mile;
float i, R, ploss;
for (volt = 100; volt <= 200; volt += 100)
{
i = 500/volt;
for (mile = 20; mile <= 100; mile += 10)
{
R = RESIST * mile;
ploss = (i*i) * R;
printf (“Voltage: %3d Miles: %3d Power Loss: %3.2fn”, volt, mile, ploss);
}
}
return 0;
}
In Visual Studio, you should open the property pages for your project.
You’re looking for:
Configuration Properties -> Linker -> System
Under the System tab, the first item listed is Subsystem. Click the little arrow on the right to bring up the listbox and choose «Console (/SUBSYTEM:CONSOLE)». Make sure after you’ve selected the subsystem that you press the «Apply» button on the bottom right corner or the change won’t take effect. After you do this, you should do a clean and build.
Alternately, just start up a new project and begin with the right type of project.
I agree with cire.
Read the error output again. It is
linker error
occurs when they cannot find where functions are defined.
«Console» program needs «main» function to stratup.
If the program cannot find «main» function, program will give linker error that says similar lines you had with just «WinMain» replaced with «main».
Windows has another form rather than «Console» program, which finds «WinMain» function instead of «main» function.
If your project setting is on «Win32 project», Your program will find «WinMain» instead of «main» function.
You only have main function, though. That is the reason why linker error happens. You didn’t defined WinMain function.
Changing the project setting to Console Program will solve the problem.
Last edited on
Thanks for the help so far. I apologize, but I posted the wrong error code for the console (it was late).
Here is what I get when I build the project as a console.
MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
I think I figured it out, cause it wasn’t saving my .c file. I had to go back and add my .c as a source file before it would show in the solution explorer. I think it was trying to compile the default powerloss.cpp (which was blank) instead of my powerloss.c.
So once I got all that worked out, this started happening to me (and it happened a few times before when I had the linker set right).
1>—— Build started: Project: PowerLoss, Configuration: Debug Win32 ——
1> ploss.c
1>d:userswilldocumentsvisual studio 2010projectspowerlosspowerlossploss.c(21): warning C4305: ‘initializing’ : truncation from ‘double’ to ‘const float’
1>d:userswilldocumentsvisual studio 2010projectspowerlosspowerlossploss.c(27): warning C4244: ‘=’ : conversion from ‘int’ to ‘float’, possible loss of data
1>d:userswilldocumentsvisual studio 2010projectspowerlosspowerlossploss.c(33): error C2065: ‘“Voltage’ : undeclared identifier
1>d:userswilldocumentsvisual studio 2010projectspowerlosspowerlossploss.c(33): warning C4047: ‘function’ : ‘const char *’ differs in levels of indirection from ‘int’
1>d:userswilldocumentsvisual studio 2010projectspowerlosspowerlossploss.c(33): warning C4024: ‘printf’ : different types for formal and actual parameter 1
1>d:userswilldocumentsvisual studio 2010projectspowerlosspowerlossploss.c(33): error C2143: syntax error : missing ‘)’ before ‘:’
1>d:userswilldocumentsvisual studio 2010projectspowerlosspowerlossploss.c(33): error C2059: syntax error : ‘bad suffix on number’
1>d:userswilldocumentsvisual studio 2010projectspowerlosspowerlossploss.c(33): error C2059: syntax error : ‘bad suffix on number’
1>d:userswilldocumentsvisual studio 2010projectspowerlosspowerlossploss.c(33): error C2017: illegal escape sequence
1>d:userswilldocumentsvisual studio 2010projectspowerlosspowerlossploss.c(33): error C2059: syntax error : ‘)’
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
When this happened to me the first time, I thought I had jacked up the code somewhere, but my instructor kept telling me the code was right. So is this some kind of configuration error? I changed the «Compile As» to «Compile as C Code (/TC)» under the advanced settings, but that doesn’t seem to fix the errors.
Any suggestions would be appreciated.
If you posted your code within code tags, which you can get using the «<>» button to the right of the edit window, then the lines would be numbered. That way, it would be easier for us to see which line is line 33.
Edit: For some reason, your printf statement is triggering a compiler error — it thinks the word «Voltage» is a code entity rather than part of a string.
Last edited on
how about just reading the error messages ?
they tell you excactly what’s the problem
In the code above, the "
symbol, as in the little symbol immediately before the capital V of Voltage, and the "
after the %3.2fn
are not what they should be, but instead are a completely different symbol that just looks similar.
So, delete those symbols, write them in yourself again using your own keyboard, and don’t copy and paste code from wherever you got that.
Put more simply, you’ve got “
and ”
where you should have "
Last edited on
@Moschops Thank you very much!! That has been my problem all along. My class doesn’t require us to compile the code, but instead they just have us submit the code in a Word document. So I was writing everything in Word, then just copying and pasting the text into the file.
@Mikeyboy I apologize, I will remember to add the line tags next time.
Topic archived. No new replies allowed.
C++ undefined reference is a linker error that often may come up when the function is declared but not implemented. These errors are usually partly identified by the linker error messages, but a programmer still needs to manually investigate the code, build system or linked libraries.
In the following article, we will mostly focus on the causes that occur in source code rather than in the build process or during library linkage. Find out the details in the upcoming paragraphs.
What Does Undefined Reference Mean in C++?
Undefined reference means that the linker is not able to find a symbol definition in any object file, but it’s still referenced. Undefined reference error is not C++ language-specific but rather a result of the executable program generation process. The latter process roughly works as follows: the compiler translates the human-readable source code into machine instructions and generates objects files. Then, the linker will try to combine all needed object files to generate an executable program or, alternatively, a library.
The linker itself can be considered as standalone software which deals with the object files and symbols defined in them. Symbols represent different entities like global variables, function names, member function names, etc.
In the following example, we have a SampleClass class that declares a constructor member. The only thing missing is that no definition is provided. So, if we try to build this program, the linker will throw an undefined reference error related to SampleClass::SampleClass() symbol.
– Code:
#include <iostream>
using std::string;
class SampleClass {private:
string user;
string name;
int number;public:
SampleClass();
};
int main() {
SampleClass sp1;
return 0;
}
– Program Output:
/usr/bin/ld: /tmp/ccoWSfKj.o: in function `main’:
tmp.cpp:(.text+0x24): undefined reference to `SampleClass::SampleClass()’
/usr/bin/ld: tmp.cpp:(.text+0x35): undefined reference to `SampleClass::~SampleClass()’
collect2: error: ld returned 1 exit status
How To Fix Undefined Reference in C++
You can fix undefined reference in C++ by investigating the linker error messages and then providing the missing definition for the given symbols. Note that not all linker errors are undefined references, and the same programmer error does not cause all undefined reference errors.
However, it’s more likely to be function-related when it’s declared somewhere, but the definition is nowhere to be found. The issue in the previous example code can be very easily traced as the program is very small.
On the other hand, huge codebases can yield undefined reference errors that may be harder to track down. The next code snippet tries to demonstrate a similar scenario which generates quite a large output of errors from the linker. Notice that the error comes from the polymorphic class SampleClass, which declares PrintContents() as a virtual function.
However, it does not even include empty curly braces to denote the body and qualify for the definition, resulting in an undefined reference error.
– Code:
#include <iostream>
#include <utility>
#include <sstream>using std::cout;
using std::endl;
using std::string;
class SampleClass {
private:
string user;
string name;
int number;public:
SampleClass(string u, string n, int num) :
user{std::move(u)}, name{std::move(n)}, number{num} {};
SampleClass(string u, int num) :
user{std::move(u)}, name{“Name”}, number{num} {} ;virtual string PrintContents() const;
string getName() const;
string getUser() const;
int getNumber() const;
};
class DerivedClass : public SampleClass {
string identifier;public:
DerivedClass(string u, string n, int num, std::string id) :
SampleClass(std::move(u), std::move(n), num),
identifier{std::move(id)} {};
string PrintContents() const override;
string getIdentifier() const;
};
string DerivedClass::getIdentifier() const {
return this->identifier;
}
string DerivedClass::PrintContents() const {
std::stringstream ss;
ss << “user: ” << this->getUser()
<< ” name: ” << this->getName()
<< ” number: ” << this->getNumber()
<< ” identifier: ” << this->identifier << ‘n’;
return ss.str();
}
string SampleClass::getName() const {
return this->name;
}
string SampleClass::getUser() const {
return this->user;
}
int SampleClass::getNumber() const {
return this->number;
}
void print(SampleClass& sp) {
cout << sp.PrintContents();
}
int main() {
auto dc1 = DerivedClass(“it”, “ai”, 5122, “tait”);
print(dc1);
return 0;
}
– Program Output:
tmp.cpp:(.text._ZN11SampleClassC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_i[_ZN11SampleClassC5ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_i]+0x1f): undefined reference to `vtable for SampleClass’
/usr/bin/ld: /tmp/cckqLhcA.o: in function `SampleClass::~SampleClass()’:
tmp.cpp:(.text._ZN11SampleClassD2Ev[_ZN11SampleClassD5Ev]+0x13): undefined reference to `vtable for SampleClass’
/usr/bin/ld: /tmp/cckqLhcA.o:(.data.rel.ro._ZTI12DerivedClass[_ZTI12DerivedClass]+0x10): undefined reference to `typeinfo for SampleClass’
collect2: error: ld returned 1 exit status
Undefined Reference in Programs Without Main Function
Undefined reference error can occur if you try to compile the source code file that does not have the main() function. To be more precise, these types of source files will yield linker errors if compiled with the usual compiler arguments.
If you intend to compile a given source file without the main() function, you should pass the special argument to not run the linker stage. The latter is usually achieved with a -c argument to the compiler command (e.g., g++ or clang++ ).
– Code:
#include <iostream>
#include <utility>
#include <sstream>using std::cout;
using std::endl;
using std::string;
class SampleClass {private:
string user;
string name;
int number;public:
SampleClass(string u, string n, int num) :
user{std::move(u)}, name{std::move(n)}, number{num} {};
SampleClass(string u, int num) :
user{std::move(u)}, name{“Name”}, number{num} {} ;
virtual string PrintContents() const;string getName() const;
string getUser() const;
int getNumber() const;
};
class DerivedClass : public SampleClass {
string identifier;
public:
DerivedClass(string u, string n, int num, std::string id) :
SampleClass(std::move(u), std::move(n), num),
identifier{std::move(id)} {};
string PrintContents() const override;
string getIdentifier() const;
};
string DerivedClass::getIdentifier() const {
return this->identifier;
}
string DerivedClass::PrintContents() const {
std::stringstream ss;
ss << “user: ” << this->getUser()
<< ” name: ” << this->getName()
<< ” number: ” << this->getNumber()
<< ” identifier: ” << this->identifier << ‘n’;
return ss.str();
}
string SampleClass::getName() const {
return this->name;
}
string SampleClass::getUser() const {
return this->user;
}
int SampleClass::getNumber() const {
return this->number;
}
void print(SampleClass& sp) {
cout << sp.PrintContents();
}
– Program Output:
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o: in function `_start’:
(.text+0x24): undefined reference to `main’
collect2: error: ld returned 1 exit status
Tracking Down Undefined Reference Errors in Derived Classes
Another useful method to easily track down undefined reference errors in large codebases is enabling compiler warnings. Sometimes these may warn that functions are referenced but never defined. In the following example, the derived class explicitly overrides a virtual function but does not provide an implementation. Note that these types of errors may also be caused when the program build script or file does not include the corresponding source file.
– Code:
#include <iostream>
#include <utility>
#include <sstream>
#include “tmp.h”using std::cout;
using std::endl;
using std::cin;
using std::string;class SampleClass {
private:
string user;
string name;
int number;
public:
SampleClass(string u, string n, int num) :
user{std::move(u)}, name{std::move(n)}, number{num} {};
SampleClass(string u, int num) :
user{std::move(u)}, name{“Name”}, number{num} {} ;
virtual string PrintContents() const { return {}; };string getName() const;
string getUser() const;
int getNumber() const;
};
class DerivedClass : public SampleClass {
string identifier;
public:
DerivedClass(string u, string n, int num, std::string id) :
SampleClass(std::move(u), std::move(n), num),
identifier{std::move(id)} {};
string PrintContents() const override;
string getIdentifier() const;
};
string DerivedClass::getIdentifier() const {
return this->identifier;
}
string SampleClass::getName() const {
return this->name;
}
string SampleClass::getUser() const {
return this->user;
}
int SampleClass::getNumber() const {
return this->number;
}
void print(SampleClass& sp) {
cout << sp.PrintContents();
}
int main() {
auto dc1 = DerivedClass(“it”, “ai”, 5122, “tait”);
print(dc1);
return 0;
}
– Program Output:
tmp.cpp:(.text._ZN12DerivedClassC2ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_iS5_[_ZN12DerivedClassC5ENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_iS5_]+0xa6): undefined reference to `vtable for DerivedClass’
/usr/bin/ld: /tmp/ccdcAqfb.o: in function `DerivedClass::~DerivedClass()’:
tmp.cpp:(.text._ZN12DerivedClassD2Ev[_ZN12DerivedClassD5Ev]+0x13): undefined reference to `vtable for DerivedClass’
collect2: error: ld returned 1 exit status
Key Takeaways
In this article, we covered common reasons that yield an undefined reference to C++ function errors and described several ways to identify them. Here are some key points to bear in mind:
- Undefined reference error is thrown by the linker rather than the compiler
- It’s usually caused by the reference to the function that has been declared, but a definition can’t be found
- Investigate linker error messages which can help to pin down the identifiers that are related to the cause of the problem
- Don’t run the linker stage on programs that don’t include the main function
Now you should be able to move on to some practical problems of analyzing linker errors and fixing them. You are definitely ready to try manually building relatively medium programs with multiple files and investigate possible causes for linker errors.
- Author
- Recent Posts
Position Is Everything: Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL.