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

Необходимо быть настолько осторожными при контакте со временем и деньгами.

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

, Но я не уверен в BigDecimal.

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

Вы только отображаете доллары при печати его. Всегда работайте с центами внутренние целые числа использования. Это может быть хитро, если потребность разделиться или должна использовать Math.abs ().

Однако Вы могли бы заботиться о способной половине цента, или даже сотый из цента. Я не знаю то, что является хорошим способом сделать это. Вы, возможно, просто должны были бы иметь дело с тысячной частью центов и использовать длинное. Или возможно Вы будете вынуждены использовать BigDecimal

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

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

156
задан sepp2k 8 March 2019 в 20:41
поделиться

6 ответов

Стандарты C99 и C ++ не требуют, чтобы функции возвращали значение. Отсутствующий оператор return в функции возврата значения будет определен (чтобы вернуть 0 ) только в функции main .

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

Из C ++ 11 черновик:

§ 6.6.3 / 2

Утечка конец функции [...] приводит к неопределенному поведению в функции, возвращающей значение.

§ 3.6.1 / 5

Если элемент управления достигает конца main , не встречая return , эффект будет результатом выполнения

 return 0;

Обратите внимание, что поведение, описанное в C ++ 6.6.3 / 2, отличается от C.


gcc выдаст предупреждение, если вы вызовете его с параметром -Wreturn-type.

-Wreturn-type Предупреждать всякий раз, когда функция определена с возвращаемым типом, который по умолчанию int. Также предупреждать о любых оператор возврата без возвращаемого значения в функции, возвращаемый тип которой не пустота (падение с конца тело функции считается возвращающим без значения), а про возврат заявление с выражением в функция, возвращаемый тип которой недействителен.

Это предупреждение активируется -Wall .


Из любопытства посмотрите, что делает этот код:

#include <iostream>

int foo() {
   int a = 5;
   int b = a + 1;
}

int main() { std::cout << foo() << std::endl; } // may print 6

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

143
ответ дан 23 November 2019 в 21:52
поделиться

gcc does not by default check that all code paths return a value because in general this cannot be done. It assumes you know what you are doing. Consider a common example using enumerations:

Color getColor(Suit suit) {
    switch (suit) {
        case HEARTS: case DIAMONDS: return RED;
        case SPADES: case CLUBS:    return BLACK;
    }

    // Error, no return?
}

You the programmer know that, barring a bug, this method always returns a color. gcc trusts that you know what you are doing so it doesn't force you to put a return at the bottom of the function.

javac, on the other hand, tries to verify that all code paths return a value and throws an error if it cannot prove that they all do. This error is mandated by the Java language specification. Note that sometimes it is wrong and you have to put in an unnecessary return statement.

char getChoice() {
    int ch = read();

    if (ch == -1 || ch == 'q') {
        System.exit(0);
    }
    else {
        return (char) ch;
    }

    // Cannot reach here, but still an error.
}

It's a philosophical difference. C and C++ are more permissive and trusting languages than Java or C# and so some errors in the newer languages are warnings in C/C++ and some warnings are ignored or off by default.

42
ответ дан 23 November 2019 в 21:52
поделиться

Under what circumstances doesn't it produce an error? If it declares a return type and doesn't return something, it sounds like an error to me.

The one exception I can think of is the main() function, which doesn't need a return statement at all (at least in C++; I don't have either of the C standards handy). If there is no return, it will act as if return 0; is the last statement.

0
ответ дан 23 November 2019 в 21:52
поделиться

Sounds like you need to turn up your compiler warnings:

$ gcc -Wall -Wextra -Werror -x c -
int main(void) { return; }
cc1: warnings being treated as errors
<stdin>: In function ‘main’:
<stdin>:1: warning: ‘return’ with no value, in function returning non-void
<stdin>:1: warning: control reaches end of non-void function
$
0
ответ дан 23 November 2019 в 21:52
поделиться

It is a constraint violation in c99, but not in c89. Contrast:

c89:

3.6.6.4 The return statement

Constraints

A return statement with an expression shall not appear in a функция с типом возврата void .

c99:

6.8.6.4 Оператор return

Ограничения

Оператор return с выражение не должно появляться в функции, возвращаемый тип которой void . Оператор return без выражения должен появляться только в функции, возвращаемый тип которой void .

Даже в режиме - std = c99 gcc будет выдает только предупреждение (хотя без необходимости включать дополнительные флаги -W , как требуется по умолчанию или в c89 / 90).

Отредактируйте, чтобы добавить это в c89, "достигнув } , завершающий функцию, эквивалентен executing a return statement without an expression" (3.6.6.4). However, in c99 the behavior is undefined (6.9.1).

-2
ответ дан 23 November 2019 в 21:52
поделиться

You mean, why flowing off the end of a value-returning function (i.e. exiting without an explicit return) is not an error?

Firstly, in C whether a function returns something meaningful or not is only critical when the executing code actually uses the returned value. Maybe the language didn't want to force you to return anything when you know that you are not going to use it anyway most of the time.

Secondly, apparently the language specification did not want to force the compiler authors to detect and verify all possible control paths for the presence of an explicit return (although in many cases this is not that difficult to do). Also, some control paths might lead into to non-returning functions - the trait that is generally non known to the compiler. Such paths can become a source of annoying false positives.

Note also, that C and C++ differ in their definitions of the behavior in this case. In C++ just flowing off the end of a value returning function is always undefined behavior (regardless of whether the function's result is used by the calling code). In C this causes undefined behavior only if the calling code tries to use the returned value.

13
ответ дан 23 November 2019 в 21:52
поделиться