Неужели беззнаковые функции должны что-то возвращать ?? - PullRequest
0 голосов
/ 01 ноября 2018

Эй, я работаю над упражнением, где мне нужно запрограммировать неподписанную функцию на C, и у меня есть вопрос, должен ли я что-то возвращать из-за типа функции ?? Или это необязательно ??

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Это хорошая идея, чтобы все ваши не-1001 * функции возвращали что-то, но если вы выходите из функции без return оценки (то есть с символом }) и пытаетесь получить доступ к ее результату, поведение не определено

Если вы исследуете различные компиляторы на Godbolt со следующим кодом в качестве источника C:

int n()
{
    int a = 1234;
}

Вы заметите, что некоторые компиляторы выдают предупреждение об этом поведении в зависимости от их уровней предупреждения.

Значение, которое вы получите, если попытаетесь использовать результирующую функцию как int, например, в printf("%d\n", n());, не определено: нет никаких гарантий относительно того, какое значение вы получите, будет ли ваша программа аварийно завершена или что-то еще целиком.

Тем не менее, в зависимости от архитектуры, для которой вы компилируете, вы можете получить локальное значение из вашей функции в качестве возвращаемого значения. Например, в архитектуре x86 почти каждое соглашение о вызовах указывает, что возвращаемое значение - это то, что находится в регистре eax при возврате функции. Так, если сгенерированный код для функции n выше сохраняет локальную переменную a в eax, «возвращаемое значение» (quote-unquote) будет 1234.

Это не то, на что вы должны когда-либо полагаться, хотя.

0 голосов
/ 01 ноября 2018

При нормальном использовании любая функция, объявленная для возврата значения, должна возвращать значение. Это во многом вопрос хорошей практики программирования. Неспособность вернуть значение часто является признаком ошибки. Однако это не требуется стандартом C, и есть два исключения.

C 2018 6.9.1 12 позволяет завершить функцию, достигнув конца ее кода без возврата значения, при условии, что вызывающая сторона не использует значение функции:

Если не указано иное, если достигается }, завершающий функцию, и вызывающая сторона использует значение вызова функции, поведение не определено.

Один случай, когда функция может возвращать значение в одних ситуациях, а не в других, - это когда она предназначена для выполнения различных действий по команде. Например:

unsigned DoSomething(int command, int parameters[])
{
    switch (command)
    {
        case GetSomething:
            …
            return Something;
        case RememberSomething;
            Something = parameters[0];
            …
            break;
    }
}

Такие конструкции могут быть подвержены ошибкам и должны тщательно рассматриваться. Поскольку объявляется, что функция возвращает значение, программист может ожидать, что она это сделает, и непреднамеренно присвоит значение функции другому объекту в ситуации, когда значение не возвращается, что приводит к неопределенному поведению.

Кроме того, функция может вообще не возвращаться, и есть спецификатор функции для явного указания компилятору, что это так, _Noreturn, как указано в 6.7.4. Такое поведение обычно используется только в нештатных ситуациях. Например, стандартные функции abort и exit завершают программу, поэтому они не возвращаются. Конечно, они объявлены с void, поэтому они никогда ничего не возвращают. Однако у вас может быть функция, которая в некоторых случаях вызывает exit, а в других возвращает целое число.

...