I currently have a function that is meant to return T (templated function). So I always assumed it MUST return a value, but I recently stumbled across something.
#define PRINTERROR(msg) \
std::cout << msg << "\n\tFILE: " << __FILE__ << "\n\tLINE: " << __LINE__ << "\n\tTIME: " << __TIME__ << std::endl << std::endl;
and this…
template<class T>
T& Container_Vector<T>::GetFirstItem()
{
#ifdef CONTAINER_VECTOR_ERROR_CHECKING_ON
if (m_iCurrentSize > 0)
{
return m_pItems[0];
}
else
{
PRINTERROR("ERROR: Attempting to retrieve item from an empty vector container");
}
#else
return m_pItems[0];
#endif
}
When I step through the code trying to test if the msg gets outputted and error checking is on the first check(m_iCurrentSize > 0) fails, the message is printed and then it appears to jump to the end of the function “}” and return nothing?
Usually I’d get a compile error saying it has to return something. What’s going on here and is it ok?
While it doesn’t actually step through onto anything that returns T it does return something, a random memory address maybe.
Omitting to return a value from a function unfortunately is not a compile error.
A compiler may emit a diagnostic message (for example g++ does if compiling with
-Walloption) but it’s not mandatory.Omitting to return a value is something that compiler writers are free to assume a programmer will never do, and if a program does it the standard says that the compiler is free to ignore the problem and whatever happens happens (undefined behavior). It’s always a programmer fault.
On x86 architecture normally the net effect is just that you will get some strange value if the function is returning a true “native” type (e.g. a
charor anint) that fits in a register and you may instead get memory corruption or a crash if the function is for example returning a class instance (e.g.std::string). Note however that any speculation about what happens in case of undefined behavior is just that… i.e. pure speculation as indeed anything may happen for the C++ language specification.