From 088ccd5a3124c6ee24e42886723e403c9f528292 Mon Sep 17 00:00:00 2001 From: Dmis Date: Sun, 7 Feb 2021 00:20:32 +0300 Subject: [PATCH] no-return --- README.md | 1 + syntax/missing_return.md | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 syntax/missing_return.md diff --git a/README.md b/README.md index f136553..a6c3418 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ 3. [Конструкторы контейнеров](syntax/stl_constructors.md) 4. [std::move](syntax/move.md) 5. [std::enable_if/std::void_t](syntax/enable_if_void_t.md) + 6. [Потерянный return](syntax/missing_return.md) 6. Исполнение программы 1. [Бесконечные циклы](runtime/endless_loop.md) 2. [Рекурсия](runtime/recursion.md) diff --git a/syntax/missing_return.md b/syntax/missing_return.md new file mode 100644 index 0000000..b57284c --- /dev/null +++ b/syntax/missing_return.md @@ -0,0 +1,38 @@ +# Забытый `return` + +Про C/C++ иногда говорят, что это языки, в которых есть специальный синтаксис для написания невалидных программ. + +В C/C++ в функции, возвращающей что-то, отличное от `void`, не обязательно должен быть `return что-то`. + +```C++ +int add(int x, int y) { + x + y; +} +``` + +Это синтаксически корректная функция, которая приведет к неопределенному поведению. Может быть мусор, может быть провал в код следующей далее по коду функции, а может быть и [«все нормально»](https://gcc.godbolt.org/z/6Y4T66). + +Особенную боль это недоразумение может доставить тем, кто пришел в C++ после какого-нибудь ориентированного на выражения языка, в котором похожий код абсолютно нормален: + +```Rust +fn add(x: i32, y: i32) -> i32 { + x + y +} +``` + +Обоснования, почему не обязательно писать в конце функции `return`, следующие: +1. В функции может быть ветвление логики. В одной из веток может вызываться код, который не предполагает возврата: бесконечный цикл, исключение, `std::exit`, `std::longjmp` или что-то иное, помеченное аттрибутом `[[noreturn]]`. Проверить на наличие такого кода не всегда возможно. +2. Функция может содержать ассемблерную вставку со специальным кодом финализации и инструкцией `ret`. + +Проверить наличие формального `return`, конечно, можно. Но нам разрешили не писать иногда (очень иногда!) чисто формальную строчку, а компиляторам разрешили не считать это ошибкой. + +------ + +С флагом `-Wreturn-type` GCC и clang во многих случаях сообщают о проблеме. + +----- +Единственным исключением, начиная с C++11, является функция `main`. В ней отсутствующий `return` к неопределенному поведению не приводит и трактуется как возврат 0. + +## Полезные ссылки +1. https://stackoverflow.com/questions/1610030/why-does-flowing-off-the-end-of-a-non-void-function-without-returning-a-value-no +2. https://en.cppreference.com/w/cpp/language/attributes/noreturn \ No newline at end of file