1

I'm writing a rather simple program following Euclidean algorithm (we have to write it using recursion). It works really well when executed in C++ Tutor but when I compile the program in the terminal, it already gives me:

warning: control may reach end of non-void function [-Wreturn-type]

When I try to execute it in the terminal, it throws:

runtime error: execution reached the end of a value-returning function without returning a value

(But I am returning a value?)

Why does it work with c++ tutor but not in the Linux terminal (using clang compiler)?

I tried to use a bunch of extra variables in the function to make the process clearer to me, but I still don't get why it thinks that there would be a case where I would not return a value.

#include <iostream>

using namespace std;

int ggt(int a, int b){

    int rest{0};
    int zaehler{0};
    int divisor{0};

    if(a>=b){
        zaehler=a;
        divisor=b;

        if(a%b==0){
            return b;   
        }
        else{
            rest=a%b;
            divisor=rest;
            zaehler=b;

            ggt(zaehler, divisor);
        }
    }
    else{
        zaehler=b;
        divisor=a;

        if(b%a==0){
            return a;   
        }
        else{
            rest=b%a;
            divisor=rest;
            zaehler=a;

            ::durchlaeufe--;
            ggt(zaehler, divisor);

        }
    }
}

int main(){

int a{40}, b{12};

    cout << "Bitte Zaehler eingeben: ";
    cin >> a;
    cout << "\n";

    cout << "Bitte Nenner eingeben: ";
    cin >> b;
    cout << "\n";

    if(ggt(a, b)==0){
        cout << "ERROR\n";
    }
    else   {
    cout << "Der groesste gemeinsame Teiler ist: " << ggt(a, b) << "\n";
    }

    return 0;
}

In this example, with a=40 and b=12, the result should be 4. And that's exactly what C++ tutor says...

PStarczewski
  • 479
  • 2
  • 17
  • In most branches `ggt` doesn't return anything. A function with a type other than `void` (and that isn't `main`) is required to `return` before control reaches the end of the function body. Edit : You probably want to change both `ggt(zaehler, divisor);` to `return ggt(zaehler, divisor);`. – François Andrieux Apr 15 '19 at 19:17
  • 1
    Possible duplicate of [Error: control may reach end of non-void function in C](https://stackoverflow.com/questions/22410538/error-control-may-reach-end-of-non-void-function-in-c) – Kevin Chen Apr 15 '19 at 19:19
  • Omg thats it thank you, I dont know why I did not see that.. – David würflinger Apr 15 '19 at 19:20
  • For what it's worth, the compilers that online C++ tutorials use sometimes do really weird things. You'd be better off with a compiler where you can read every warning. My guess would be that C++ Tutor is suppressing or hiding warnings from you and that your code relies on Undefined Behavior. [Here](https://stackoverflow.com/questions/55269252/what-is-going-on-with-getsstdin-on-the-site-coderbyte) is another example of a really weird compiler from a C++ tutorial – alter_igel Apr 15 '19 at 19:22
  • 1
    A good time to enable ALL compiler warnings! And not any should be silently ignored! – Klaus Apr 15 '19 at 19:24
  • If the compiler has the option (like `-Werror`) to make warnings errors, take advantage of it. This forces you to deal with them before having to pull out the debugger to find out what went wrong at runtime. – user4581301 Apr 15 '19 at 19:53

1 Answers1

1

the actual answer (missing return at recursion call) was already given.

i'd like to add a simpler version for you to compare and maybe learn something :)

int ggt(int a, int b)
{
    if (a < b)
    {
        std::swap(a, b);
    }

    if (a%b == 0)
    {
         return b;
    }

    return ggt(b, a%b);
 }

short explanation:

  • the "swap" when a < b ensures b contains the smaller value.
  • the "rest" (a%b) is calculated directly when calling the recursion (this avoids storing intermediate values)
  • as you see the control flow is simpler, so it is easier to reason about each step of the execution.
skeller
  • 1,151
  • 6
  • 6