Unresolved external link in C++ function [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
I keep getting the following errors and can't seem to resolve them:
error LNK2019: unresolved external symbol "double __cdecl orderIn(double,double,double)" (?orderIn##YANNNN#Z) referenced in function _main
fatal error LNK1120: 1 unresolved externals
I know there is something wrong with the way I am trying to pass the variable through the functions but I just can't get it. I want the information gathered and calculated in the first function to pass through and be utilized by the second function. I have tried numerous methods to no avail.
What am I missing here?
Thanks!
#include <iostream>
#include <iomanip>
using namespace std;
double orderIn(double, double, double);
void shippingOut(double, double, double);
double spoolsOrdered,
spoolsInStock,
shipping,
total,
backordered,
charges,
spoolsShipping;
int main()
{
orderIn(spoolsOrdered, spoolsInStock, shipping);
shippingOut(spoolsShipping, backordered, total);
return 0;
}//end int main
double orderIn(double &spoolsOrdered, double &spoolsInStock, double &shipping)
{
char extracharge;
//spools ordered
cout << "How many spools would you like to order? ";
cin >> spoolsOrdered;
while (spoolsOrdered < 1)
{
cout << "That is not a valid entry ";
cin >> spoolsOrdered;
}
//spools in stock
cout << "How many spools are currently in stock? ";
cin >> spoolsInStock;
//extra charges
cout << "Are there any special charges on this order? ";
cin >> extracharge;
//special charges
if ( extracharge == 'Y' || extracharge == 'y')
{
cout << "What is the additional charge per spool? ";
cin >> charges;
shipping = (10 + charges);
}
else
shipping = 10;
return (&spoolsOrdered, &spoolsInStock, shipping);
}
void shippingOut(double spoolsOrdered, double spoolnStock, double shipping)
{
double backordered;
double subTotal;
double totalShipping;
double total;
double spoolsShipping;
if (spoolsOrdered > spoolsInStock)
{
backordered=(spoolsOrdered - spoolsInStock);
cout << "There are " << spoolsInStock << " spools ready to be shipped./n";
cout << "The remaining " << backordered <<" are on backorder.";
spoolsShipping=spoolsInStock;
}
else
{
cout << "All " <<spoolsOrdered << " spools ordered are ready to ship.\n";
spoolsShipping=spoolsOrdered;
}
//Product Charges
subTotal = spoolsShipping * 100;
cout << "Subtotal: $" << subTotal << endl;
//Shipping Charges
totalShipping = spoolsOrdered * shipping;
cout << "S/H Total: $" << totalShipping << endl;
//Total
total = subTotal + totalShipping;
cout << "The total of the order ready to ship is: $" << total << endl;
}

You declare:
double orderIn(double, double, double);
and then use it. You later define:
double orderIn(double &spoolsOrdered, double &spoolsInStock, double &shipping)
This is a different function; the argument types are references to double, not simple double.
Fix either the declaration or the definition — it looks like you really need to fix the declaration since you want to set the variables in the calling function:
double orderIn(double &, double &, double &);
You should also review why you have so many global variables, and why the global variable names are shadowed by the parameters. Avoid globals whenever possible.
a) when I tried to run it in the past, I could only get it to work by defining the variables before main. Where should all of these variables be declared?
Normally, you'll declare variables in a function (in this case, main()), and then pass the variables to functions that need to use them. Sometimes, globals are appropriate. So, I expected:
int main()
{
double spoolsOrdered = 0.0;
double spoolsInStock = 0.0;
double shipping = 0.0;
double total = 0.0;
double backordered = 0.0;
double spoolsShipping = 0.0;
orderIn(spoolsOrdered, spoolsInStock, shipping);
shippingOut(spoolsShipping, backordered, total);
// Use these values?
return 0;
}
If you don't have a use for the values in main(), why are you passing them around in the first place.
Then I noticed that both orderIn() and shippingOut() return a double, but you don't use the value. What does orderIn() return? There's a surprise:
return (&spoolsOrdered, &spoolsInStock, shipping);
This doesn't do what you think it does. The commas are the comma operator. The address of spoolsOrdered is evaluated and discarded; the address of spoolsInStock is evaluated and discarded; then the value in shipping is returned. You could change the function to return void and remove the return statement altogether, similar to shippingOut().
The global variable charges should be a local variable in orderIn().
b) what is the relationship between the variables and the parameters?
Inside the function orderIn(double &spoolsOrdered, double &spoolsInStock, double &shipping), the parameters each hide a global variable of the same name. Since this is C++, you can still access the global variable by using the scope operator :: like this:
::spoolsOrdered // The global variable
spoolsOrdered // The local reference variable -- a reference to the global
Largely by coincidence, it ends up being much the same in this case, but if you had value parameters or pointer parameters, or if the call did not pass the global variables as the reference parameters, the effects would be quite different.
If you use GCC (g++), the -Wshadow option reports shadowing problems.

Your function prototype is:
double orderIn(double, double, double);
However your actual function definition is:
double orderIn(double &spoolsOrdered, double &spoolsInStock, double &shipping)
{
}
double and double& are different types, thus you need to either adjust the prototype or the definition.

Related

Paint Job Estimator C++

Hi I am working on a project for school and cannot for the life of me figure out how to get the totalJobCost function to work. The other functions work without a problem but i don't think they are passing the var back to main for totalJobCost to grab as the totalJobCost outputs 0. here is the code that i am using:
#include "stdafx.h"
#include <iostream>
using namespace std;
void space(double paintarea, double paintcost, double paintneeded, double totalpaint);
void cost(double hrs, double hrcost, double spacetopaint);
void totalJobCost(double allTheirPaintCost, double allTheirWages, double theirTotalJobCost);
const double AREA_FORMULA = 220.00;
const double AREAFORMULA_PAINT = 1.00;
const double AREAFORMULA_HOURS = 8.00;
const double AREAFORMULAHOURS_WAGES = 35.00;
int main()
{
double areaTP;
double paintCST = 0;
double paintNeeded = 0;
double allPaintCost = 0;
double hoursNeeded = 0;
double hoursWages = 0;
double allWages = 0;
double allJobCost = 0;
cout << "Enter the square footage you need to paint, then press enter" << endl;
cin >> areaTP;
cout << "Enter the price by gallons of paint you will use, then press enter" << endl;
cin >> paintCST;
while (paintCST < 10)
{
cout << "Enter the price by gallons of paint you will use, then press enter. cannot be less than 10 :";
cin >> paintCST;
}
space(areaTP, paintCST, paintNeeded, allPaintCost);
cost(hoursNeeded, hoursWages, areaTP);
totalJobCost(allPaintCost, hoursWages, allJobCost);
system("Pause");
return 0;
}
void space(double paintarea, double paintcost, double paintneeded, double totalpaint)
{
paintneeded = paintarea / AREA_FORMULA * AREAFORMULA_PAINT;
totalpaint = paintneeded * paintcost;
cout << "How many gallons of paint you will need: " << paintneeded << endl;
cout << "Your total paint cost will be: " << totalpaint << endl;
}
void cost(double hrs, double hrcost, double spacetopaint)
{
hrs = (spacetopaint / AREA_FORMULA) * AREAFORMULA_HOURS;
hrcost = hrs * AREAFORMULAHOURS_WAGES;
cout << "The number of hours for the job will be: " << hrs << endl;
cout << "The total amount of wages will be: " << hrcost << endl;
}
void totalJobCost(double totalpaint, double hrcost, double theirTotalJobCost)
{
theirTotalJobCost = totalpaint + hrcost;
cout << "The total price of your paint job will be: " << theirTotalJobCost << endl;
}
You need to declare your arguments (totalpaint and hrcost) as references.
Currently, functions space() and cost() just make copies of totalpaint and hrcost when called, update them, then print them. But when the functions return, the values stored in totalpaint and hrcost are lost.
To fix this, you should declare those functions as follows:
void space(double paintarea, double paintcost, double paintneeded, double& totalpaint)
void cost(double hrs, double& hrcost, double spacetopaint)
Now whatever variable you pass in as totalpaint or hrcost will be updated when space() or cost() operates on it.
This is a pass by value vs. pass by reference issue.
In C++, booleans, characters, integer numbers, floating-point numbers,
arrays, classes—including strings, lists, dictionaries, sets, stacks,
queues—and enumerations are value types, while references and pointers
are reference types.
CPP reference
The variables you are using are doubles (double precision floating point), so they are value types. When you pass value type variables to functions as parameters, the current value of the variables is copied to the calling stack of the function you called. Once inside the function, the parameter names are just names you use to access the copied values. Whatever you do to these copied values will not affect the value of the original variables you passed to the function. Read up on function scope and the calling stack architecture of C/C++ to understand more.
To change the value of a variable across function calls, you need to pass a reference to its location in memory. If you declare a variable in the first few lines of a function, its location in memory will be part of that function’s call stack, and you can safely access that memory in any function calls that are called within the original function. So you can do this:
int main() {
double variable = 0;
function(&variable);
cout << variable;
}
void function(double* variable_address) {
*variable_address = 1.5;
}
This involves the dereference operator. Sorry if this is too much info, but pass by reference and pass by value are easier to understand if you know what’s happening in the underlying function call and memory architecture of C/C++.

Trouble understanding how elements of a certain function work

I am required to fully understand the following code :
#include <iostream>
using namespace std;
double area(double length, double width);
double time(double p_area, double h_area, double mow_rate);
int main() {
double d_plot_length, d_plot_width, d_home_side, d_mow_rate;
double plot_area, home_area, time_taken;
// I've used double for all of these to get the most precise values possible, something I'd only really consider doing on small programmes such as this
cout << "What is the length of the plot? In meters please." << endl;
cin >> d_plot_length;
cout << "What is the width of the plot? In meters please." << endl;
cin >> d_plot_width;
cout<< "What is the size of the side of the house? In meters please." << endl;
cin >> d_home_side;
cout << "What is the rate at which you are going to be mowing? In meters per minute please" << endl;
cin >> d_mow_rate;
// Just getting all the data I need from the user
plot_area = area(d_plot_length, d_plot_width);
home_area = area(d_home_side, d_home_side);
time_taken = time(plot_area, home_area, d_mow_rate);
cout << "It will take " << time_taken << " minutes to mow this lawn. Better get cracking" << endl;
return 0;
}
double area(double length, double width) {
double value;
value = length * width;
return value;
}
double time(double p_area, double h_area, double mow_rate) {
double value;
value = (p_area - h_area) / mow_rate;
return value;
}
I am struggling to understand how the time() function works.
So far I understand that :
time_taken , gets its value from the time() function: time(plot_area, home_area, d_mow_rate).
The time() function gets its values from the function declaration at the bottom.
double time(double p_area, double h_area, double mow_rate) {
double value;
value = (p_area - h_area) / mow_rate;
return value;
}
However, this is where I'm stuck. The user is asked to enter values for d_plot_length, d_plot_width, etc. So I cannot understand how the compiler knows what these values p_area, and h_area actually are.
I realise that somehow the area() function is being used to aid the time() function, but as far as I'm aware the variables P_area etc within the time() function do not have values assigned to them.
Please can someone fill in the gaps in my understanding.
To be more precise, I want to know exactly how time_taken is displayed on the screen, from the start of the process, to the cout. Like I say I am familiar with most areas but not all.
In your program, you had computed the following values:
plot_area = area(d_plot_length, d_plot_width);
home_area = area(d_home_side, d_home_side);
When the method area(double,double) is invoked, the resultant double value gets stored in these variables.
Then you have the function call:
time_taken = time(plot_area, home_area, d_mow_rate);
This is the call by value type of function invocation. A copy of the values in the variables, plot_area, home_area and d_mow_rate are passed to the function. In the time(double, double, double) the computing is done upon the basis of the logic you had defined in this method and the resultant value is returned to the function call in the main() method.
Please note that the function call is of call by value and hence only a copy of the values are passed to the arguments mentioned in the function time(double, double, double) even though the variable names are the same in the main() and in the function call.
For further reading, I will suggest you to have a look at the following links:
Call By
Value
Call By
Reference
Call By
Pointer

Trouble with simple functions

I am writing code to call functions having to do with force, mass, and acceleration equations. The functions are called correctly, but the inputs are not multiplied as they should be. My output for the first function is a crazy small number, and the output for the first function is always 0.
Here is my code. Any feedback wold be very helpful. Thanks.
#include <iostream>
#include <cstdlib>
using namespace std;
void displayMenu();
double force(double);
double secondForce(double,double);
int main(int argc, char** argv)
{
int menuOption;
displayMenu();
system("PAUSE");
return 0;
}
void displayMenu(void)
{
int menuOption;
double weight, accel;
cout << " Main Menu" << endl;
cout << "Enter 1 for Force calculation with acceleration = 9.8m/s^2.\n";
cout << "Enter 2 for Force calculation with user defined acceleration.\n";
cout << "Enter 3 to quit the program.\n";
cin >> menuOption;
if(menuOption==1)
{
cout << "Enter a mass.\n";
cin >> weight;
cout << "The force is ";
cout << force(weight);
cout << "N.";
}
else if(menuOption==2){
cout << "Enter a mass.\n";
cin >> weight;
cout << "Enter an acceleration.\n";
cin >> accel;
cout << "The force is ";
cout << secondForce(weight, accel);
cout << "N.";
}
}
double force(double weight)
{
double force, mass;
force=(mass*(9.8));
return force;
}
double secondForce(double secondMass, double secondWeight)
{
double secondForce, mass, acceleration;
secondForce=(mass*acceleration);
return secondForce;
}
You are using uninitialized variables in your functions. Using these uninitialized variables in your program is undefined behavior.
force=(mass*(9.8)); << mass has a garbage value
secondForce=(mass*acceleration); << mass and acceleration have a garbage value
I think you meant to have
double force(double weight)
{
return weight * 9.8;
}
double secondForce(double secondMass, double secondAccel)
{
return secondMAss * secondAccel;
}
The problem is you are using variables in your calculation that are undefined. See my embedded comments below:
double secondForce(double secondMass, double secondWeight)
{
double secondForce, mass, acceleration;
secondForce=(mass*acceleration); //what is the value of mass and acceleration here??
return secondForce;
}
As a side note: Consider stepping through your code inside of a debugger like gdb so you can see how your program executes. Trying to reason through it is very difficult for large programs. In your example, it's easy to spot for an experienced programmer.
You're multiplying the data by garbage values
double force(double weight)
{
double force, mass;
force=(mass*(9.8));
return force;
}
double secondForce(double secondMass, double secondWeight)
{
double secondForce, mass, acceleration;
secondForce=(mass*acceleration);
return secondForce;
}
What's the value of mass and acceleration here? These variables are not initialized. You have to assign some values to them first.
You should enable compiler warnings and pay attention to them. For example, here is what MSVC says even on the lowest warning level:
warning C4700: uninitialized local variable 'mass' used
warning C4700: uninitialized local variable 'mass' used
warning C4700: uninitialized local variable 'acceleration' used
In C++, using an uninitialised variable is never a good idea. Unlike in other languages, most variables in C++ are not automatically initialised with 0 values. This causes your program to inhibit unspecified or undefined behaviour when the value contained in the variable is to be accessed.
Be safe and correct. Initialise! For example:
double force = 0.0;
double mass = 0.0;
Note that the language also allows you to first initialise, then assign, then use the variable. For example:
double force;
force = 0.0;
cout << force;
But that's bad style. Why leave a variable uninitialised and then later assign something when you can do everything in one step? Leaving the variable uninitialised first also prevents you from making it const.
Ensuring correct initialisation of all variables will make the behaviour of your program defined and consistent. You will have other problems, though, because you multiply the 0 mass, which will always result in 0 and is certainly not what you intend. However, deterministic behaviour is a good starting point to fix the wrong math.

What's wrong in this C++ code? (Console)

To me, this code seems to have no errors, and it is correct in the way I learnt C++. What may be wrong?
This is my code:
#include<iostream>
#include<cstdlib>
#include<string>
#include<cmath>
using namespace std;
double Calculation(long double x, long double y);
void Output(long double s, long double d, long double p, long double q);
void main(){
long double a;
long double b;
long double sum;
long double difference;
long double product;
long double quotient;
cout << "Enter your first number." << endl;
cin >> a;
cout << "Enter your second number." << endl;
cin >> b;
Calculation(a, b);
Output(sum, difference, product, quotient);
system("pause");
}
double Calculation(long double x, long double y){
long double sum;
long double difference;
long double product;
long double quotient;
sum = x + y;
difference = x - y;
product = x * y;
quotient = x / y;
return sum;
return difference;
return product;
return quotient;
}
void Output(long double s, long double d, long double p, long double q){
cout << "The sum of your numbers is " << s << "." << endl;
cout << "The difference between your numbers is " << d << "." << endl;
cout << "The product of your numbers is " << p << "." << endl;
cout << "The quotient of your numbers is " << q << "." << endl;
}
Explanation: This is a calculator which works by the variables 'a' and 'b'. It calculates the sum, difference, product, and quotient of 'a' and 'b' by the function Calculate and outputs the answers with the function Output.
Error: uninitialized local variable 'quotient' used.
uninitialized local variable 'product' used.
uninitialized local variable 'difference' used.
uninitialized local variable 'sum' used.
Lots of things are wrong with your code, but there is a single root cause to this - a misunderstanding of how the return statement works.
You have a function with multiple return statements. It appears that you think that all of these statements would execute; that assumption is incorrect. Only the first return statement reached in a function is executed; the remaining ones are ignored.
Moreover, you appear to imply that return statement would influence variables in the caller automatically; it wouldn't. In order to modify a variable in the caller, the caller itself needs to assign the returned value.
If you need your function to return multiple values, you need to change the approach: it should take multiple arguments by reference, and modify them, like this:
void Calculation(long double x, long double y, long double &sum,
long double &difference, long double &product, long double &quotient) {
sum = x + y;
difference = x - y;
product = x * y;
quotient = x / y;
}
You also need to change the prototype declaration of Calculation, like this:
void Calculation(long double x, long double y, long double &sum,
long double &difference, long double &product, long double &quotient);
Call Calculation like this:
Calculation(a, b, sum, difference, product, quotient);
This will solve your compilation issue, and the code will run correctly.
The problem is that you declare the variables listed in the error message as local variables. That means that no other function will be able to use them. Declaring them again in another function declares new local variables.
In this case you might want to declare the variables as global variables. This is done by moving the definitions outside of any function, and only have that definition and not in a function.
In your main function you are not setting any values to those variables before passing them to the Output() function - therefore they are 'uninitialized'. Also, as mentioned in some comments, there are a number of other problems there too, here's a couple:
1) You can't do multiple returns in a function on the same logic path
2) You are not collecting the return of Calculation() anyway
I expect you can fix your issues by passing some of those variables by reference instead.
As others said, the direct cause of your problem is misunderstanding on how the return and scoping works.
When dealing with C++ the compiler/linker warnings can be cryptic and/or confusing. In your example, the compiler should warn you about unreachable code after first return, however Visual Studio 2013 with default default does not do that.
You can make it do that by enabling all warnings, which is a good practice anyway. In project properties go to Configuration Properties -> C/C++ -> General -> Warning level and select EnableAllWarnings.
Final advice: if you are programming for fun or learning how to program, I'd advise you to start with C# or Java, which are easier and have better tool support.

Pounds and Ounces to Kilograms and grams. Driver Program Fail

#include<iostream>
using namespace std;
void convertWeight(double ounces, double grams, int pounds, int kilograms);
double output(double ounces, int pounds);
int main()
{
double ounces, grams;
int pounds, kilograms;
char answer;
do
{
cout << "Enter weight in pounds and ounces: " << endl;
cin >> pounds >> ounces;
cout << output(pounds, ounces) << endl;
cout << "Do you want to test again (y/n)?: " << endl;
cin >> answer;
}while (answer == 'y' || answer == 'Y');
return 0;
}
double output(double ounces, int pounds)
{
double grams;
int kilograms;
convertWeight(ounces, grams, pounds, kilograms);
cout << pounds << "pounds and " << ounces << "ounces = " << kilograms << "kilograms and " << grams << " grams." << endl;
return 0;
}
void convertWeight(int pounds, double ounces, int &kilograms, double &grams)
{
double temp = (pounds + ounces/16)/2.2046
kilograms = temp;
grams = (temp - kilograms) * 1000;
}
Alright I am trying to write a program that converts pounds and ounces to kilograms and grams. I must have pounds and kilograms as type int and ounces and grams as type double. I feel like there is something I have not done here. I am trying to use a driver program and call a function both by call-by-value and call-by reference parameters. I just compiled my program and got the longest list of errors I have ever seen and has errors I never seen before either. What is it that I have not added to the program that I should have?
here is my following error list:
warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data
warning C4101: 'kilograms' : unreferenced local variable
warning C4101: 'grams' : unreferenced local variable
error C2146: syntax error : missing ';' before identifier 'kilograms'
warning C4244: '=' : conversion from 'double' to 'int', possible loss of data
You need to append parameter types in function implementation: void convertWeight(ounces, grams, pounds, kilograms)
I can't read all the error messages there, but I can tell you at least part of what's wrong with your programme :-)
void convertWeight(ounces, grams, pounds, kilograms)
{
kilograms = (pounds + ounces/16)/2.2046;
grams = kilograms * 1000;
return(kilograms, grams);
}
Here, you've said that the function return type is void, i.e it doesn't return a value -- but then you've tried to return a value anyway! (In a way that isn't valid C++.) Furthermore, you've forgotten to specify the parameter types in the function definition, which is also not allowed in C++.
Rather than outputting a pair of values (which is possible, but in a different way to how you've tried to do it here), it would be easier to pass the grams and kilograms variables by reference -- this means that the function you call will change the variables you pass to them. You need to change your convertWeight function signature to
// Note the '&' on the reference variables
void convertWeight(int pounds, double ounces, int& kilograms, double& grams)
{
kilograms = // whatever
grams = // whatever
}
Now you can call convertWeight() like this:
int pounds = 3;
int ounces = 12;
int kilograms;
double grams;
convertWeight(pounds, ounces, kilograms, grams);
and your function will fill in the values of kilograms and grams for you.
There's a lot wong in the code. Let me concentrate on the convertWeight function.
First of all, write the types of the parameters in front of the parameter names, like you did with the output function.
Secondly, the function parameters are all "in" parameters, meaning they are used to pass in values which are copied to be used in the function. The function itself is allowed to modify them, but modifications are done locally and thrown away when returning from the function. You wanted to return two values which is not possible in C++ unless you wrap them into a single container type like std::pair. If you don't want to do this, you need to make two of your parameters "out" parameters, which can be done in C++ using references.
Finally, the conversion is wrong. Your assignment of the converted kilograms is stored in an int, which means that the decimal part is truncated. When multiplying by 1000 afterwards, you get a number divisible by 1000 which doesn't help much; even if it still was a double, your grams variable would not only have the grams but the full weight. I'm almost sure you only wanted to have the "remainder" of the kilograms expressed in grams. So use a temporary double variable to fix the first problem and subtract the kilograms before multiplying by 1000 to fix the second problem.
void convertWeight(double ounces, double &grams, int pounds, int &kilograms)
{
double temp = (pounds + ounces/16)/2.2046;
kilograms = temp; // will automatically truncate to full kilograms
grams = (temp - kilograms) * 1000; // Will use the remainder
}
Also I don't like the parameter order, but that's a personal choice of preference. Typically you want to keep ins and outs separate. Also it makes more sense to put the "larger" unit before the "smaller" unit, resulting in this signature:
void convertWeight(int pounds, double ounces, int &kilograms, double &grams)