I have the following test code:
#include <cstdint>
#include <cassert>
enum class Result : std::uint32_t {SUCCESS = 0, INSUCCESS = 1};
void* func(Result& result)
{
// works great
/*
result = Result::INSUCCESS;
return NULL;
*/
// error: invalid conversion from ‘long int’ to ‘void*’ [-fpermissive]
/*
return result = Result::INSUCCESS, NULL;
*/
// compiles, but <result> is not set???
return result = Result::INSUCCESS, nullptr;
}
void testReturnWithSideEffects()
{
Result result = Result::SUCCESS;
func(result);
assert(result == Result::INSUCCESS);
}
There are 2 questions here but I'm mostly interested in the second:
Why is result not set?
Edit: Thanks to everyone for confirming this. The work-around that I have decided to use is to replace:
return result = Result::INSUCCESS, nullptr;
with the following:
return result = Result::INSUCCESS, (void*)NULL;
Additional note: of course my production scenario is with another pointer type (not void*) but I simplified for illustrative purposes.
Another note: from the workaround you can tell that there's something fishy going on with that nullptr. I'm guessing that the example line which doesn't compile, should actually compile, and these 2 matters are probably related somehow.
And a 3rd and final note, to those who outlined the "trickery" or "unreadability" of my code: readability is largely a subjective matter, for instance I can argue that a shorthand like this can make the code more structured which can actually help spot defects.