1

this program crash with clang

#include <iostream>
#include <string>
#include <mutex>
#include <functional>

int main(int argc, char **argv)
{
    auto m = std::function<void()>( [](){
        int r = std::rand() % 100;
        if (r < 50)
        {
            return r; //should not return
        }
    });
    for(int i=0;i<100;i++)
        m();
    return 0;
}

reports:

pt@test$ clang++ -o test test1.cpp  -std=c++11
    test1.cpp:14:5: warning: control may reach end of non-void lambda [-Wreturn-type]
    });
    ^
1 warning generated.
pt@test$ ./test
Illegal instruction (core dumped)

but, it doesn't crash with g++.

My confusion is that since it will cause an crashing, why not clang treat it as an error while compiling?


update

consider following code

auto lMayNotReturn = []() {
    int rValue = std::rand() % 100;
    if (rValue < 50)
    {
        return rValue; //should not return
    }
    std::cout << "   non-return rValue: " << rValue << std::endl;
};
for(int i=0 ; i< 30;i++){
    int rValue= lMayNotReturn();
    std::cout << "random value " << rValue << " ";
    if (rValue >= 50) {
        std::cout << " ???undefined???";
    }
    std::cout << std::endl;
}
std::cout << "end--------" << std::endl;

targets generated by gcc & visual studio will keep running and return random values as

 pt@DESKTOP-S54JIQA:/mnt/e/Projects/uv_test$ ./test
   non-return rValue: 83
random value 6295680  ???undefined???
   non-return rValue: 86
random value 6295680  ???undefined???
   non-return rValue: 77
random value 6295680  ???undefined???

Bugs like this are far more difficult to track down than simply crashing and clang wins.

The only reason for clang not raising an error that I can think of is compatibility.

Arnold
  • 23
  • 3
  • 9
    Roses are red, violets are blue, undefined behaviour is undefined. – n. m. could be an AI Oct 29 '18 at 07:22
  • 1
    BTW, if you are using your lambda locally you don't need to wrap it into `std::function` - it just adds a few layers of indirection that the compiler probably won't be able to unwrap. – Matteo Italia Oct 29 '18 at 07:24
  • 1
    You know, Clang did try to warn you. You can't take from this that it doesn't have your best interests at heart. – StoryTeller - Unslander Monica Oct 29 '18 at 07:24
  • I am actually quite curious about how different compiler think about `undefined` behavior and why they differ. – Arnold Oct 29 '18 at 08:07
  • It is only an error if control actually reaches the end, so the compiler would need to prove that the function is ever called, and that `std::rand() % 100` will be `>= 50` at least once, which means that it would have to determine which random numbers `std::rand()` is going to produce in the future, which is a lot to ask from a compiler. – molbdnilo Oct 29 '18 at 08:12
  • You should compile with a higher warning level and look at (and fix) the warnings you get from the compiler. – Werner Henze Oct 29 '18 at 08:16
  • I do not understand what is being asked. Given ill-formed buggy code, it sometimes crashes. Why is this surprising? – Eljay Oct 29 '18 at 12:36

1 Answers1

5

Because this is undefined behavior. For return statement:

Flowing off the end of a value-returning function (except main) without a return statement is undefined behavior.

That means compilers are allowed to do anything; they're not required to give an error (or not).

songyuanyao
  • 169,198
  • 16
  • 310
  • 405