Question about runRYWTransaction without return in lamda

I accidentally forgot to add return Void() in the lamda function in runRYWTransaction , (example blow). It still compiles but cause segmentation fault when it runs.

wait(runRYWTransaction(cx, [](Reference<ReadYourWritesTransaction> tr) -> Future<Void> {
			tr->setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS);
			tr->setOption(FDBTransactionOptions::LOCK_AWARE);
			tr->clear(someKey);
			//return Void();
		}));

I’m trying to figure out how the segmentation fault happens.
After some digging, I feel this may be caused by “auto-deduction” that compiler implicitly return Future<Void>() for lamda function without explicit return type. Since the default constructor for Future is a null pointer, it has segmentation fault.

Talking with Jingyu on this and there may be another possible explanation:
If there is no return in lamda function, the compiler just points the return to the default location that should host the return value. Since we don’t return anything, that area is invalid.

My question is:

  1. Which of the explanation is true?
  2. Can we make compiling fail in this scenario?

Note: In GCC, there is a warning on no-return-value for the function. Maybe we just make compiling fail on warnings?

Flowing off the end of a function […] results in undefined behavior in a value-returning function. That’s how the segfault happens.

Run cmake with -DUSE_WERROR=ON to make compiling fail on warnings

1 Like