[Linker error] undefined reference to `WinMain@16'

I've just learned how to split a program in more subprograms and how I can create header files, but I didn't figure out how I can make the main program work.

The errors that appear (when I try to compile the source files) are:
1. median.cpp
1
2
  [Linker error] undefined reference to `WinMain@16'
  ld returned 1 exit status   


2. grade.cpp

1
2
3
  [Linker error] undefined reference to `median(std::vector<double, std::allocator<double> >)' 
  [Linker error] undefined reference to `WinMain@16'
  ld returned 1 exit status 


3. student_info.cpp

1
2
  [Linker error] undefined reference to `WinMain@16'
  ld returned 1 exit status   


4. 4_data_headers_partitioning.cpp (the main program)
1
2
3
4
  [Linker error] undefined reference to `read(std::istream&, Student_info&)' 
  [Linker error] undefined reference to `compare(Student_info const&, Student_info const&)' 
  [Linker error] undefined reference to `grade(Student_info const&)' 
  ld returned 1 exit status  


I attached the source files here: http://www.2shared.com/file/US8dNvZz/partitioning.html

Can you help me a little? What I do wrong? Or what I omit?
Thanks in advance for your help.

(I'm using dev c++ 4.9.9.2 under windows)
I can't find where to download your files, maybe posting it helps?

Anyway, are you sure you've compiled all your source files before linking?
It seems like you are trying to compile all the cpp files as separate programs (hence, looking for WinMain in the other cpps). I don't know how dev c++ works, but there is probably a way to specify a "project" or something that indicates that your files are together a single program.
Yes, start Dev-C++ and create a new Project. Add your main program's cpp file, then add the other cpp files you intend to use in your project. Make sure you create a "Console Application" project -- not a Windows (GUI) application project.

Then use Dev-C++ to compile the whole project.

Good luck!
I added the files into a new project (console application). But again a new error [Build Error] No rule to make target... - I solved that by changing project's path. It seems Dev-C++ has some problem with paths and spaces.

I compiled the project (I also compiled every file it contains) and everything was ok, Done. with no errors. But when I run the project, the console appears (the black window with a white cursor :P ) and nothing happens.

The project looks like this:

1
2
3
4
5
6
7
8
4_patitioning
           4_data_headers_partitioning.cpp
           median.cpp
           median.h
           grade.cpp
           grade.h
           student_info.cpp
           student_info.h


You can see the source code below:

4_data_headers_partitioning.cpp (main file)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <algorithm>
#include <iomanip>
#include <ios>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#include "grade.h"
#include "Student_info.h"
using std::cin; using std::setprecision;
using std::cout; using std::sort;
using std::domain_error; using std::streamsize;
using std::endl; using std::string;
using std::max; using std::vector;
int main()
{
    vector<Student_info> students;
    Student_info record;
    string::size_type maxlen = 0; // the length of the longest name
    // read and store all the students data.
    // Invariant: students contains all the student records read so far
    // maxlen contains the length of the longest name in students
    while (read(cin, record)) 
          {
          // find length of longest name
          maxlen = max(maxlen, record.name.size());
          students.push_back(record);
          }
    // alphabetize the student records
    sort(students.begin(), students.end(), compare);
    // write the names and grades
    for (vector<Student_info>::size_type i = 0;i != students.size(); ++i) 
          {
          // write the name, padded on the right to maxlen + 1 characters
          cout << students[i].name<< string(maxlen + 1 - students[i].name.size(), ' ');
          // compute and write the grade
          try 
              {
              double final_grade = grade(students[i]);
              streamsize prec = cout.precision();
              cout << setprecision(3) << final_grade<< setprecision(prec);
              } 
          catch (domain_error e) 
              {
              cout << e.what();
              }
          cout << endl;
          }
    return 0;
}


median.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// source file for the median function
#include <algorithm> // to get the declaration of sort
#include <stdexcept> // to get the declaration of domain_error
#include <vector> // to get the declaration of vector
using std::domain_error; using std::sort; using std::vector;
// compute the median of a vector<double>
// note that calling this function copies
double median(vector<double> vec)
{
       typedef vector<double>::size_type vec_sz;
       vec_sz size = vec.size();
       if (size == 0)
       throw domain_error("median of an empty vector");
       sort(vec.begin(), vec.end());
       vec_sz mid = size / 2;
       return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
}


median.h

1
2
3
4
5
6
#ifndef GUARD_median_h
#define GUARD_median_h
// median.h—final version
#include <vector>
double median(std::vector<double>);
#endif 


grade.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdexcept>
#include <vector>
#include "grade.h"
#include "median.h"
#include "Student_info.h"
using std::domain_error; using std::vector;
// compute a student's overall grade from midterm and final exam grades and homework grade
double grade(double midterm, double final, double homework)
       {
       return 0.2 * midterm + 0.4 * final + 0.4 * homework;
       }
// compute a student's overall grade from midterm and final exam grades
// and vector of homework grades.
// this function does not copy its argument, because median does so for us.
double grade(double midterm, double final, const vector<double>& hw)
    {
    if (hw.size() == 0)
    throw domain_error("student has done no homework");
    return grade(midterm, final, median(hw));
    }
double grade(const Student_info& s)
    {
    return grade(s.midterm, s.final, s.homework);
    }


grade.h

1
2
3
4
5
6
7
8
9
#ifndef GUARD_grade_h
#define GUARD_grade_h
// grade.h
#include <vector>
#include "Student_info.h"
double grade(double, double, double);
double grade(double, double, const std::vector<double>&);
double grade(const Student_info&);
#endif 


Student.info

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// source file for Student_info-related functions
#include "Student_info.h"
using std::istream; using std::vector;
bool compare(const Student_info& x, const Student_info& y)
     {
     return x.name < y.name;
     }
istream& read(istream& is, Student_info& s)
     {
     // read and store the student's name and midterm and final exam grades
     is >> s.name >> s.midterm >> s.final;
     read_hw(is, s.homework); // read and store all the student's homework grades
     return is;
     }
     // read homework grades from an input stream into a `vector'
istream& read_hw(istream& in, vector<double>& hw)
     {
     if (in) 
        {
        // get rid of previous contents
        hw.clear();
        // read homework grades
        double x;
        while (in >> x)
        hw.push_back(x);
        // clear the stream so that input will work for the next student
        in.clear();
        }
     return in;
     }


Student_info.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef GUARD_Student_info
#define GUARD_Student_info
// Student_info.h header file
#include <iostream>
#include <string>
#include <vector>
struct Student_info 
       {
       std::string name;
       double midterm, final;
       std::vector<double> homework;
       };
bool compare(const Student_info&, const Student_info&);
std::istream& read(std::istream&, Student_info&);
std::istream& read_hw(std::istream&, std::vector<double>&);
#endif 


Thanks for reading this... I hope I'll make it run.

LE: From now on I'm using Code::Blocks (Dev-C++ was way to old and buggy), but i have the same problem: Console opening, allowing me to insert 2 line of letters, then execution ends without a result.
Last edited on
I have a vague idea about a possible problem, but have you tried debugging it to see where the problem is?
I think this is the reason for your complaint:
http://www.cplusplus.com/forum/articles/7312/

A couple of comments on the input functions:
The istream::clear() function does not reset the input stream. It clears all error flags. --There is a big difference.

Before I continue further, suppose I input the following student information:
John 95 100 80 88
Jane 96 99 81 81
Joseph 84 92 82 82
Aleah 97 100 83 83

The first time through the read() function, you read "John" as the student name, "95" as his midterm, an "100" as his final. Then you move into the read_hw() function, where you read homework grades of "80" and "88". Since no error has occurred, the function continues and attempts to read "Jane" as the next homework grade. This, of course, fails, so the function terminates, and it is required to clear() the input stream's error flags so that you can continue with the next function. (This design is, BTW, the reason why your input has to terminate twice for the program to continue.)

Since each line is its own record, it is better to read the entire line, then use a stringstream to break it up.

Hope this helps.

[edit] Oh yeah, I forgot to mention that lines 18 and 21 in Student_info.cpp are mutually exclusive, and hence, unnecessary. Good luck!
Last edited on
Thanks a lot for helping me with this. Not the console closing was the problem (I admit I had that problem with "Hello, world!" :P but I just used system(), I know it a bad habit, but I promise I'll get rid of that when I finish this book I'm reading on C++)

The real problem was that I got lost somewhere on the road when I wrote the program (headers, functions, data structures, partitioning programs etc. - a lot of information in a short period) and I forgot the input format (john 100 100 100...). I was hitting Enter after each word or number.

I admit this was a struggle. But at the end I've learned a lot (especially not to forget the program's purpose :D). Thanks again. See you around.
Topic archived. No new replies allowed.