ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
When compiling my program, I received the following error message:
Code:
/tmp/ccbx5rJi.o: In function `evaluateExpression(theOperator, linkedStack<int>&, char*, int&)':
eval.cc:(.text+0x1cd): undefined reference to `outputExpression(int, char*, int)'
/tmp/ccbx5rJi.o: In function `computeOperator(theOperator, linkedStack<int>&, linkedStack<theOperator>&, char*, int&)':
eval.cc:(.text+0x3a4): undefined reference to `evaluateExpression(theOperator, linkedStack<int>&, char*, int)'
/tmp/ccbx5rJi.o: In function `main':
eval.cc:(.text+0x554): undefined reference to `computeOperator(theOperator, linkedStack<int>&, linkedStack<theOperator>&, char*, int)'
collect2: ld returned 1 exit status
All three functions mentioned are contained within the main file. They all have a function prototype listed at the top of the file. I am not sure where to even look to begin to debug this.
I hadn't issued any commands - I was merely compiling the program.
The following is the code:
Code:
/*
*
* This program will take a mathematical expression and evaluate
* it according to the proper orders of precedence.
*
*/
#include <iostream>
#include "linkedStack.h"
/* This struct will define the data type of the operator, which
consists of the operator sign itself and of a precedence level
to determine if this data will be put onto the operator stack
or if it will be immediately evaluated */
struct theOperator {
int precedenceLevel;
char operatorSign;
};
/* function prototypes */
int getOperand(char);
theOperator getOperator(char, int);
void computeOperator(theOperator, linkedStack<int>&,
linkedStack<theOperator>&, char*, int);
void evaluateExpression(theOperator, linkedStack<int>&,
char*, int);
void outputExpression(int, char*, int);
int main()
{
char nextTokenIn;
char expressionArray[80];
int arrayIndex = 0;
int currentOperand;
int parenLevel = 0;
theOperator currentOperator;
linkedStack<int> operandStack;
linkedStack<theOperator> operatorStack;
std::cout << "Please begin to input the expressions:\n";
while ((nextTokenIn = std::cin.get()) != '.') {
expressionArray[arrayIndex++] = nextTokenIn;
if (nextTokenIn == '(')
parenLevel++;
else if (nextTokenIn == ')')
parenLevel--;
/* todo: create error message for parenthesis levels */
else if (isdigit(nextTokenIn)) {
currentOperand = getOperand(nextTokenIn);
operandStack.push(currentOperand);
}
else if (isalpha(nextTokenIn)) {
currentOperator = getOperator(nextTokenIn, parenLevel);
computeOperator(currentOperator, operandStack,
operatorStack, expressionArray,
arrayIndex);
}
else
std::cin.ignore();
}
return 0;
}
/*
* The getOperand function will take a number from the input stream
* and will assign it to an int variable. It takes the stream
* character by character and builds up a complete interger.
*
* Inputs: char tokenIn - the character from the input stream
*
* Returns: int num1 - the constructed integer
*/
int getOperand(char tokenIn)
{
int num1 = (tokenIn - '0');
while (!isspace(tokenIn = std::cin.get())) {
num1 = (num1 * 10) + (tokenIn - '0');
}
return num1;
}
/*
* The getOperator function will take a character from the input
* stream and will assign it to a theOperator variable. It will
* also compute the precedence level for the variable and assign
* that value to the theOperator variable.
*
* Inputs: char tokenIn - the character from the input stream
* int parenLevel - the variable to calculate the level
* of parenthesis in the expression
*
* Returns: theOperator currentOperator - the variable that holds
* the operator and the precedence level
*/
theOperator getOperator(char tokenIn, int parenLevel)
{
theOperator currentOperator;
currentOperator.operatorSign = tokenIn;
switch (currentOperator.operatorSign) {
case ';':
currentOperator.precedenceLevel = 0;
break;
case '+':
case '-':
currentOperator.precedenceLevel = 1;
break;
case '*':
case '/':
currentOperator.precedenceLevel = 2;
break;
/* default:
error message */
}
currentOperator.precedenceLevel += (parenLevel * 10);
return currentOperator;
}
/*
* The computeOperator function will take the currentOperator and
* analyze it to see what to do. If its precedence level is greater
* than that on the top of the operator stack, it is pushed onto the
* operator stack. If and while its precedence level is greater than
* or equal to the top of the stack, it is evaluated with a call to
* evaluateExpression(); If the entire expression is completed, a
* call to outputExpression is made.
*
* Inputs: theOperator currentOperator - the variable that holds
* the operator and the precedence level
* linkedStack<int>& operandStack - the operand stack;
* passed by reference to work directly on it
* linkedStack<theOperator>& operatorStack - the operator
* stack; passed by reference to work directly
* on it
* char* expressionArray - holds the entire expression
* which will be used to print out in the
* outputExpression() function
* int& arrayIndex - holds the index position for inserting
* new tokens into expressionArray, will be
* reset to zero in outputExpression() function
*
* Returns: none by return, operandStack and operatorStack
* by reference - result is
*/
void computeOperator(theOperator currentOperator,
linkedStack<int>& operandStack,
linkedStack<theOperator>& operatorStack,
char* expressionArray, int& arrayIndex)
{
theOperator topOfStack;
topOfStack = operatorStack.top();
if (currentOperator.precedenceLevel > topOfStack.precedenceLevel)
operatorStack.push(currentOperator);
else if (currentOperator.precedenceLevel
<= topOfStack.precedenceLevel) {
operatorStack.push(currentOperator);
topOfStack = currentOperator;
while (currentOperator.precedenceLevel
<= topOfStack.precedenceLevel) {
operatorStack.pop();
evaluateExpression(currentOperator, operandStack,
expressionArray, arrayIndex);
topOfStack = operatorStack.top();
}
}
/* todo: create error message if not enough operands */
}
/*
* The evalusteExpression function will take the top two operands
* from the operand stack and evaluate them with the operator that
* is currently being processed.
*
* Inputs: theOperator currentOperator - the variable that holds
* the operator and the precedence level
* linkedStack<int>& operandStack - the operand stack;
* passed by reference to work directly on it
* char* expressionArray - holds the entire expression
* which will be used to print out in the
* outputExpression() function
* int& arrayIndex - holds the index position for inserting
* new tokens into expressionArray, will be
* reset to zero in outputExpression() function
*
* Returns: none by return, operandStack by reference - result is
* pushed back onto the operand stack
*/
void evaluateExpression(theOperator currentOperator,
linkedStack<int>& operandStack,
char* expressionArray, int& arrayIndex)
{
int righthandOperand, lefthandOperand, result;
if (currentOperator.operatorSign == ';') {
result = operandStack.top();
operandStack.pop();
outputExpression(result, expressionArray, arrayIndex);
}
else {
righthandOperand = operandStack.top();
operandStack.pop();
lefthandOperand = operandStack.top();
operandStack.pop();
}
/* todo: create error message if not enough operands */
switch (currentOperator.operatorSign) {
case '+':
result = lefthandOperand + righthandOperand;
operandStack.push(result);
break;
case '-':
result = lefthandOperand - righthandOperand;
operandStack.push(result);
break;
case '*':
result = lefthandOperand * righthandOperand;
operandStack.push(result);
break;
case '/':
result = lefthandOperand / righthandOperand;
operandStack.push(result);
break;
}
}
/*
* The outputExpression function will print out the whole
* expression that has been evaluated and also the result. This
* function will also clear out any values that need to be reset
* to evaluate the next expression.
*
* Inputs: int result - the result of the expression
* char*& expressionArray - holds the entire expression
* which will be used to print out the
* expression entered
* int& arrayIndex - holds the index position for inserting
* new tokens into expressionArray, will be
* reset to zero
* Returns: none by return, char& expressionArray[] and
* int& arrayIndex by reference and are flushed
* clean of all data.
*/
void outputExpression(int result, char* expressionArray,
int& arrayIndex)
{
std::cout << std::endl << expressionArray
<< " = " << result << std::endl;
for (arrayIndex = 0; arrayIndex < 80; arrayIndex++) {
*(expressionArray + arrayIndex) = '\0';
}
arrayIndex = 0;
}
I hadn't issued any commands - I was merely compiling the program.
Did gcc invoke itself? I'm asking how you ran the compiler - what options and arguments you used... in other words what command you entered to run the compiler.
I only examined evaluateExpression. The function prototype does not match the definition - in the prototype the fourth argument is an int, in the definition it is a reference to an int. You should make these match, and that when you call the function, that the types match also.
Did gcc invoke itself? I'm asking how you ran the compiler - what options and arguments you used... in other words what command you entered to run the compiler.
No options. Just:
% g++ eval.cc
Quote:
Originally Posted by matthewg42
I only examined evaluateExpression. The function prototype does not match the definition - in the prototype the fourth argument is an int, in the definition it is a reference to an int. You should make these match, and that when you call the function, that the types match also.
I can't believe I was so stupid. It was because I didn't match the prototypes with the function headers. The headers were correct, I forgot to tell the prototypes that the last int was a reference.
I guess that error message scared me half to death and froze my meager mind. I had never seen anything like it (shows how inexperienced I am) and didn't know where to look.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.