1

I am trying to call a function from an external file to a source file. However, when I do so I'm getting the following error:

Build Error Visual Studio C++

Why am I getting the following errors? I've been trying to get my head around it all day, but it has all been in vain. P.S I'm am very new to the language and programming in general. Past experience: Python

source.cpp

#include <iostream>
#include <string>
#include "func.cpp"
using namespace std;

double pow(double x, int y);

int main()
{
    double x;
    int y;
    double answer;

    cout << "Choose a number: " << endl;
    cin >> x;
    cout << "Raised to the power: " << endl;
    cin >> y;

    answer = pow(x, y);

    cout << "Answer: " << answer << endl;

    return answer;
}

func.cpp

double pow(double x, int y)
{
    double result = 1;
    if (x == 0 && y == 0)
    {
        result = -1;
    }
    else
    {
        if (y == 0)
        {
            result = 1;
        }
        else if (y < 0)
        {
            x = 1.0 / x;
            y *= -1;
        }
        for (int i = 0; i < y; i++)
        {
            result *= x;
        }

    }

    return result;
}
  • 2
    You seem to have forgotten about [`std::pow`](http://en.cppreference.com/w/cpp/numeric/math/pow), but the compiler haven't. Please read [Why is “using namespace std” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Some programmer dude Jun 02 '18 at 00:08
  • 2
    Error messages are text. Put them in your post as text. And for goodness sake, if you *do* need to use an image, at least crop it to the smallest size needed. We don't need to see your entire desktop for the small error message window at the bottom right. Be considerate of those who are viewing from a mobile device or metered connection, at least. What would someone reading this post from a phone or tablet be able to see in that gigantic image you posted for no reason? – Ken White Jun 02 '18 at 00:09
  • And don't include source files. What you're doing is creating a single [*translation unit*](https://en.wikipedia.org/wiki/Translation_unit_(programming)). There are no "external files" in the program you show. – Some programmer dude Jun 02 '18 at 00:11

2 Answers2

4

A couple things going on here. The most immediate is one of the header's you've included is declaring pow or std::pow. As much as I'd like to blame it all on using namespace std;, the good ol' C pow function is good enough to derail the compiler. The compiler finds two pows with similar enough parameters and doesn't know which one to use. Instead name your function mypow or place it in your own namespace.

Eg: func.cpp

namespace my
{ 
    double pow(double x, int y)
    {
        // guts of pow are unchanged
    }
}

and in source.cpp

double pow(double x, int y);

becomes

namespace my
{ 
    double pow(double x, int y);
}

and is called

answer = my::pow(x, y);

That solves problem 1.

Problem 2 is a linker problem you haven't seen yet. In your project func.cpp is going to be compiled to func.obj. func.cpp is also included in source.cpp. An included function is effectively pasted into the including file so, you now have two copies of everything in func being compiled. pow can be found inside func.obj and source.obj.

This becomes a problem when the linker tries to assemble func.obj and source.obj into a single executable file. the Linker finds two pows and, similar to the compiler, doesn't know which to use.

The standard rule of thumb is do not include cpp files. Let the compiler compile them and the linker link them. Create a header that exposes the functions in the cpp file that need to be used externally and have the users include the header.

This make your program look like

func.h

#pragma once
namespace my
{
    double pow(double x, int y);
}

func.cpp

namespace my
{ 
    double pow(double x, int y)
    {
        double result = 1;
        if (x == 0 && y == 0)
        {
            result = -1;
        }
        else
        {
            if (y == 0)
            {
                result = 1;
            }
            else if (y < 0)
            {
                x = 1.0 / x;
                y *= -1;
            }
            for (int i = 0; i < y; i++)
            {
                result *= x;
            }

        }

        return result;
    }
}

source.cpp

#include <iostream>
#include <string>
#include "func.h"
using namespace std;

int main()
{
    double x;
    int y;
    double answer;

    cout << "Choose a number: " << endl;
    cin >> x;
    cout << "Raised to the power: " << endl;
    cin >> y;

    answer = my::pow(x, y);

    cout << "Answer: " << answer << endl;

    return answer;
}

Unrelated, but good reading: Why is "using namespace std" considered bad practice?

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • Thank you for the wholesome answer. It fixed all the problems related to compiling etc and makes sense why they were happening in the first place. However, one more thing. Once I've complied and I run my program, the output window crashes/closes after I give it the first two inputs, without displaying the output answer? Any idea to why that may be? – Sarwan Shah Jun 02 '18 at 10:49
  • @SarwanShah Nothing jumps out at me as program crashing wrong. Visual Studio has one of the best debuggers and this is a fairly short program. If it is not already, set Visual Studio to generate a debug build. Then place a breakpoint on `answer = my::pow(x, y);` and run the program. Use the step functions to run the program line by line when the program crashes you will know where and you can use the variables displayed to help you find out why. – user4581301 Jun 02 '18 at 17:22
0

Here is all you need to do in order to fix the issue:

Step 1-

change the second c++ file into a c++ header file by changing the extension to '.hpp' and in the other file.

Step 2-

remove line 6 from source.cpp

The above should fix your issue.

Caleb Evans
  • 31
  • 1
  • 8
  • Unfortunately this answer fixes little. Because the cpp file is being included, it is behaving exactly the same as it would as a header file, at least at this point. There will be a linker error once the compiler errors are resolved. – user4581301 Jun 02 '18 at 00:19