Undefined symbols for architecture arm64: - confused with putting it all together

Getting a error:
Undefined symbols for architecture arm64:
"grade(Student_info const&)"
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)



I'm trying to learn from an old book (2001)
Accelerated C++ Practical Programming by Example
by Andrew Koenig, Barbara E. Moo


it's starting to seem like it's too advanced for my current level. but nonetheless, I like how it's progressing by have a case study and teaching programming by example.

i'm trying to consolidate the codes from page 101 to 111 of the book.

originally, it's meant to use
#include "grade.h"
#include "Student_info.h"

as i haven't tried linking files before. i thought i could combine the codes from grade.h and Student_info.h
into one single file. there were more compilation errors, which i managed to resolve all except this

error: use of undeclared identifier 'x'

it seems like this book is getting too advanced for me. should i put it on hold and focus on other books instead?
1) Beginning C20 from novice to professional
and
2) Programming Principles and Practice Using C++ 2nd Edition by Bjarne Stroustrup


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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#include <algorithm> 
#include <iomanip> 
#include <ios>
#include <iostream> 
#include <stdexcept> 
#include <string> 
#include <vector> 



using std::cin;
using std::cout;
using std::domain_error; 
using std::endl;
using std::max;
using std::setprecision; 
using std::sort;
using std::streamsize; 
using std::string;
using std::vector;
using std::istream;

double median(std::vector<double>);

double median (double); 			// argument type should be vector<double>

double grade(double, double, double);
double grade(double, double, const std::vector<double>&); 
// double grade(const Student_info&);




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>&); 



double grade(const Student_info&);


double median(vector<double> vec)
{
//	typedef vector<double>::size_type vec_sz;
	
//	vec_sz size = vec.size(); 


	const auto size {vec.size()};			// coded by seeplus
	
	if (size == 0)
		throw domain_error("median of an empty vector");

		sort(vec.begin(), vec.end());
		
//		vec_sz mid = size / 2;

		const auto mid { size /2 };			// coded by seeplus
		
		return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid]; 
		
}


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)); 
	
	return (midterm + final + median(hw)) / 3;
}





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; 
}













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; 
	}



Last edited on
That is one of the clearer error messages.

On line 109 you use a variable x that hasn't been declared.

I think you would be better to stick to the book rather than consolidating code from other sources. If you compile it with the online compiler here there are other (avoidable) errors.
Last edited on
thanks, lastchance.


now the error i'm facing on my own compiler ( mac terminal g++)
is
Undefined symbols for architecture arm64:
"grade(Student_info const&)"
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


and when i try to use the online compiler, there's a lot more other problems waiting.


I think you would be better to stick to the book rather than consolidating code from other sources.


the problem is not that I'm trying to consolidate code from other sources.

but rather, the book
Accelerated C++ Practical Programming by Example
by Andrew Koenig, Barbara E. Moo

doesn't present an end solution as one complete code.

instead, it talks about the problem and design concept while presenting the codes block by block. and it's up to me to combine the separate blocks of code together to try to make it work.


perhaps this book is too advanced for me at my current level. but it has been enlightening in certain aspects.
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

double median( std::vector<double> );
double grade(double, double, double);
double grade(double, double, const std::vector<double>&);

struct Student_info { std::string name; double midterm, final; std::vector<double> homework; };
double grade(const Student_info&);
bool compare(const Student_info&, const Student_info&);
std::istream& read( std::istream&, Student_info& );
std::istream& read_hw( std::istream&, std::vector<double>& );

double median( std::vector<double> vec )
{
    if( vec.empty() ) throw std::domain_error("median of an empty vector");
    
    if( vec.size() == 1 ) return vec.front() ; // *** added ***

    std::sort(vec.begin(), vec.end());

    const auto mid = vec.size() / 2 ; 

    return vec.size() % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
}

double grade( double midterm, double final, const std::vector<double>& hw )
{
	if( hw.empty() ) throw std::domain_error("student has done no homework");
	return ( midterm + final + median(hw) ) / 3 ;
}

// *** definition added ***
double grade( const Student_info& info ) { return grade( info.midterm, info.final, info.homework ) ; }

bool compare( const Student_info& x, const Student_info& y )
{ return x.name < y.name; }


std::istream& read( std::istream& is, Student_info& s )
{
    is >> s.name >> s.midterm >> s.final;
    return read_hw( is, s.homework ); // read and store all the student's homework grades
}

// read homework grades from an input stream into a `vector'
std::istream& read_hw( std::istream& in, std::vector<double>& hw )
{
	if (in)
    {
        // get rid of previous contents
        hw.clear();

        // read homework grades double x;
        double x ; // **** added ****
        while( in >> x ) hw.push_back(x);

        // clear the stream so that input will work for the next student
        in.clear();
    }

    return in;
}

int main()
{
    // ...
    // ...
}
thanks JLBorges,
for helping me with this grinding.

do you think i should put this book on hold first, go improve my basics with other more introductory books, or do that concurrently?
Try to do the exercises from this book particularly, the set of exercises at the end of each chapter. Avoid copy and paste; after having had a look at the snippets in the book, try to write the program on your own.

The Stroustrup book (PP&P) too has good educative exercises.
thanks JLBorges,

i was trying to compile the overall code first, run, to see the results, know what to expect...

before trying to write the program from scratch again.
Dear JLBorges,

there's still one error left

1
2
3
4
5
6
7
8
9
error: no matching function for call to 'grade'
        double final_grade = grade(students[i]); 

note: candidate function not viable: requires 3 arguments, but 1 was provided
double grade(double midterm, double final, const vector<double>& hw)
       ^
note: candidate function not viable: requires 3 arguments, but 1 was provided
double grade(double, double, double);


above code is within int main()

i'v double-checked the book, I have written the code exactly as the author has wrote...




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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <algorithm> 
#include <iomanip> 
#include <iostream> 
#include <stdexcept> 
#include <string> 
#include <vector> 



using std::cin;
using std::cout;
using std::domain_error; 
using std::endl;
using std::max;
using std::setprecision; 
using std::sort;
using std::streamsize; 
using std::string;
using std::vector;
using std::istream;

double median(std::vector<double>);

double grade(double, double, double);
double grade(double, double, const std::vector<double>&); 
// double grade(const Student_info&);




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>&); 



double median(vector<double> vec)
{
	if( vec.empty() ) throw std::domain_error("median of an empty vector");
	
	if( vec.size() == 1 ) return vec.front(); 
	
	std::sort(vec.begin(), vec.end());
	
	const auto mid = vec.size() /2 ;
	
		
	return vec.size() % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid]; 
		
}


double grade(double midterm, double final, const vector<double>& hw)
{
	if (hw.empty())
	throw domain_error("student has done no homework");
	
	
	return (midterm + final + median(hw)) / 3;
}





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; 
}













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; 
	}
Define the function.
See lines #37, #38 in http://www.cplusplus.com/forum/beginner/281694/#msg1218770
The above code isn't correct.

L24 declares a function grade(double, double, double), but there is no provided function definition. Warning bit not an error as this function isn't used elsewhere

L160 calls a function grade with one argument of type Student_info. This function is not declared/defined.

Does the book have this function definition elsewhere (on a different page possibly)?

This compiles:

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>

struct Student_info {
	std::string name; double midterm, final;
	std::vector<double> homework;
};

double median(std::vector<double>);
double grade(double, double, const std::vector<double>&);
double grade(const Student_info&);
bool compare(const Student_info&, const Student_info&);
std::istream& read(std::istream&, Student_info&);
std::istream& read_hw(std::istream&, std::vector<double>&);

double median(std::vector<double> vec) {
	if (vec.empty())
		throw std::domain_error("median of an empty vector");

	if (vec.size() == 1)
		return vec.front();

	std::sort(vec.begin(), vec.end());

	const auto mid = vec.size() / 2;

	return vec.size() % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid];
}

double grade(const Student_info& si) {
	return grade(si.midterm, si.final, si.homework);
}

double grade(double midterm, double final, const std::vector<double>& hw) {
	if (hw.empty())
		throw std::domain_error("student has done no homework");

	return (midterm + final + median(hw)) / 3;
}

bool compare(const Student_info& x, const Student_info& y) {
	return x.name < y.name;
}

std::istream& read(std::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;
	return read_hw(is, s.homework); // read and store all the student's homework grades
}

// read homework grades from an input stream into a `vector'
std::istream& read_hw(std::istream& in, std::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;
}

int main() {
	std::vector<Student_info> students;
	Student_info record;
	std::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(std::cin, record)) {
		// find length of longest name
		maxlen = std::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 (std::vector<Student_info>::size_type i = 0; i != students.size(); ++i) {
		// write the name, padded on the right to maxlen + 1 characters
		std::cout << students[i].name << std::string(maxlen + 1 - students[i].name.size(), ' ');

		// compute and write the grade
		try {
			double final_grade = grade(students[i]);
			std::streamsize prec = std::cout.precision();

			std::cout << std::setprecision(3) << final_grade << std::setprecision(prec);
		}
		catch (std::domain_error e) {
			std::cout << e.what();
		}
		std::cout << '\n';
	}

	return 0;
}

Last edited on
I have learnt.

thank you, JLBorges and seeplus
Topic archived. No new replies allowed.