C++ c++;函数在应该返回时似乎不返回任何内容

C++ c++;函数在应该返回时似乎不返回任何内容,c++,function,C++,Function,我目前有一个函数,它将返回T(模板函数)。所以我一直认为它必须返回一个值,但最近我偶然发现了一些东西 #define PRINTERROR(msg) \ std::cout << msg << "\n\tFILE: " << __FILE__ << "\n\tLINE: " << __LINE__ << "\n\tTIME: " << __TIME__ << std::endl << st

我目前有一个函数,它将返回T(模板函数)。所以我一直认为它必须返回一个值,但最近我偶然发现了一些东西

#define PRINTERROR(msg) \
std::cout << msg << "\n\tFILE: " << __FILE__ << "\n\tLINE: " << __LINE__ << "\n\tTIME: " << __TIME__ << std::endl << std::endl;
#定义打印错误(msg)\

std::cout这是未定义的行为,如果定义了
CONTAINER\u VECTOR\u ERROR\u CHECKING\u
,并且
!(m_iccurrentsize>0)
那么您就不会返回任何内容。您可能会收到警告,但不会收到错误,因为您确实有一个条件返回。在这种情况下,函数返回垃圾,并且堆栈可能在此之后损坏。

这是未定义的行为,如果定义了
容器\u向量\u错误\u检查
!(m_iccurrentsize>0)
那么您就不会返回任何内容。您可能会收到警告,但不会收到错误,因为您确实有一个条件返回。在这种情况下,函数返回垃圾,堆栈在此之后可能已损坏。

#ifdef
块中的
PRINTERROR
之后缺少
return
。不这样做会导致未定义的行为。必须在函数末尾返回适当的值


(这种逻辑错误可以在编译时通过设置适当的标志来捕获。例如,在g++中,您可以使用
-Wall

#ifdef
块中的
PRINTERROR
之后缺少
返回。不这样做会导致未定义的行为。必须在函数末尾返回适当的值


(这样的逻辑错误可以在编译时捕获,并设置相应的标志。例如,在g++中,可以使用
-Wall

首先,预处理在编译之前进行。对于编译器,代码如下所示-

如果定义了
容器\u向量\u错误\u检查

template<class T>
T& Container_Vector<T>::GetFirstItem()
{
    if (m_iCurrentSize > 0)
    {
        return m_pItems[0];
    }
    else
    {
        PRINTERROR("ERROR: Attempting to retrieve item from an empty vector container");
    }
}

您的第一个案例并非在所有分支上都有回报,您至少应该得到一个警告。MSVS不会报告编译错误,但会返回警告。您得到的随机数只是函数退出之前返回寄存器中的最后一个值

首先,预处理在编译之前进行。对于编译器,代码如下所示-

如果定义了
容器\u向量\u错误\u检查

template<class T>
T& Container_Vector<T>::GetFirstItem()
{
    if (m_iCurrentSize > 0)
    {
        return m_pItems[0];
    }
    else
    {
        PRINTERROR("ERROR: Attempting to retrieve item from an empty vector container");
    }
}

您的第一个案例并非在所有分支上都有回报,您至少应该得到一个警告。MSVS不会报告编译错误,但会返回警告。您得到的随机数只是函数退出之前返回寄存器中的最后一个值

不幸的是,忽略从函数返回值不是编译错误

编译器可能会发出诊断消息(例如,如果使用
-Wall
选项编译,g++会发出诊断消息),但这不是强制性的


省略返回值是编译器编写者可以自由假设程序员永远不会做的事情,如果程序执行了,标准规定编译器可以自由忽略问题和发生的任何事情(未定义的行为)。这总是程序员的错误


在x86体系结构上,通常的净效果是,如果函数返回一个真正的“本机”类型(例如,
char
int
),并且适合寄存器,那么您可能会得到一些奇怪的值,例如,如果函数返回一个类实例,您可能会得到内存损坏或崩溃(例如,<>代码> STD::String )。但是,注意任何关于未定义行为的发生的猜测,即,C++语言规范中可能会发生纯猜测,如“确实>强>任何< /强>。 编译器可能会发出诊断消息(例如,如果使用
-Wall
选项编译,g++会发出诊断消息),但这不是强制性的


忽略返回值是编译器编写人员可以自由假设程序员永远不会做的事情,如果程序执行了,标准规定编译器可以自由忽略问题和发生的任何事情(未定义的行为)。这始终是程序员的错误


在x86体系结构上,通常的净效果是,如果函数返回一个真正的“本机”类型(例如,
char
int
),并且适合寄存器,那么您可能会得到一些奇怪的值,例如,如果函数返回一个类实例,您可能会得到内存损坏或崩溃(例如,
std::string
)然而,注意到在不确定行为的情况下发生的任何猜测只是……即纯猜测,如“确实>强>任何< /强>可能发生在C++语言规范中。

AOK。只是不知道编译在某个点上没有返回的东西。f返回的是什么,或者幕后发生的其他事情是否会导致问题?@Ben Y:您正在调用未定义的行为,因此发生的是…嗯,未定义!实际发生的情况将取决于实现、调用约定等。堆栈可能会因某个返回内容的函数脱落而损坏,没有实际返回任何内容。啊,好吧。只是不知道在某个时候不返回任何内容就可以编译。堆栈是否可能因为返回的内容而损坏,或者是幕后发生的其他事情导致了问题?@Ben Y:您正在调用未定义的行为,所以发生的是…嗯,未定义d!实际发生的情况将取决于实现、调用约定等。堆栈可能会由于从返回某个内容的函数上脱落而损坏,而实际上没有返回任何内容。
template<class T>
T& Container_Vector<T>::GetFirstItem()
{
    return m_pItems[0];
}