C ++ функция, кажется, не возвращает ничего, когда это должно - PullRequest
1 голос
/ 30 сентября 2011

В настоящее время у меня есть функция, которая предназначена для возврата T (шаблонная функция). Поэтому я всегда предполагал, что он ДОЛЖЕН возвращать значение, но недавно наткнулся на что-то.

#define PRINTERROR(msg) \
std::cout << msg << "\n\tFILE: " << __FILE__ << "\n\tLINE: " << __LINE__ << "\n\tTIME: " << __TIME__ << std::endl << std::endl;

и это ...

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
}

Когда я перебираю код, пытаясь проверить, выводится ли сообщение msg и происходит ли проверка ошибок при первой проверке (m_iCurrentSize> 0), происходит сбой, сообщение печатается и затем кажется, что оно переходит к концу функции "} и ничего не вернуть?

Обычно я получаю сообщение об ошибке компиляции, говорящее, что оно должно что-то возвращать. Что здесь происходит, и это нормально?

Хотя на самом деле он не переходит на что-либо, что возвращает T, он действительно что-то возвращает, может быть случайный адрес памяти.

Ответы [ 4 ]

3 голосов
/ 30 сентября 2011

Вы пропускаете return после PRINTERROR в блоке #ifdef. В противном случае неопределенное поведение . Вы должны вернуть соответствующее значение в конце функции.

(Такая логическая ошибка может быть обнаружена во время компиляции с установленными флагами. Например, в g ++ вы можете использовать -Wall.)

1 голос
/ 30 сентября 2011

Прежде всего, предварительная обработка происходит перед компиляцией. Для вашего компилятора код выглядит как -

Если определено CONTAINER_VECTOR_ERROR_CHECKING_ON:

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");
    }
}

, если CONTAINER_VECTOR_ERROR_CHECKING_ON НЕ определено:

template<class T>
T& Container_Vector<T>::GetFirstItem()
{
    return m_pItems[0];
}

Ваш первый случай не имеет возврата по всем веткам, вы должны получить как минимум предупреждение. MSVS не сообщает об ошибке компиляции, но возвращает предупреждение. Случайное число, которое вы получаете, является просто последним значением, присутствующим в регистре возврата перед выходом из функции.

0 голосов
/ 30 сентября 2011

Пропуск возврата значения из функции, к сожалению, не является ошибкой компиляции.

Компилятор может выдавать диагностическое сообщение (например, g ++ делает при компиляции с опцией -Wall)но это не обязательно.

Пропуск возврата значения - это то, что авторы компилятора могут предполагать, что программист никогда этого не сделает, и если программа делает это, стандарт говорит, что компилятор может игнорировать проблему ичто бы ни случилось (неопределенное поведение).Это всегда ошибка программиста.

В архитектуре x86 обычно чистый эффект состоит в том, что вы получите какое-то странное значение, если функция возвращает истинный "родной" тип (например, char или int), который помещается в регистр, и вы можете вместо этого получить повреждение памяти или сбой, если функция, например, возвращает экземпляр класса (например, std::string).Тем не менее, обратите внимание, что любые предположения о том, что происходит в случае неопределенного поведения, это просто ... то есть чистые предположения, поскольку все, что может произойти для спецификации языка C ++.

0 голосов
/ 30 сентября 2011

Это неопределенное поведение, если CONTAINER_VECTOR_ERROR_CHECKING_ON определено и !( m_iCurrentSize > 0 ), то вы ничего не возвращаете.Вы можете получить предупреждение, но не ошибку, поскольку у вас есть одно условие return.В таком случае функция возвращает мусор, и, возможно, после этого стек будет поврежден.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...