Difference between revisions of "cpp/utility/unreachable"
From cppreference.com
YexuanXiao (Talk | contribs) m |
|||
(18 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
{{cpp/title|unreachable}} | {{cpp/title|unreachable}} | ||
− | {{cpp/utility/navbar}} | + | {{cpp/utility/program/navbar}} |
− | {{ddcl | header=utility | since=c++23 | | + | {{ddcl|header=utility|since=c++23| |
[[noreturn]] void unreachable(); | [[noreturn]] void unreachable(); | ||
}} | }} | ||
− | Invokes undefined behavior. An implementation may use this to optimize impossible code branches away (typically, in optimized builds) or to trap them to prevent further execution (typically, in debug builds). | + | Invokes [[cpp/language/ub|undefined behavior]] at a given point. |
+ | |||
+ | An implementation may use this to optimize impossible code branches away (typically, in optimized builds) or to trap them to prevent further execution (typically, in debug builds). | ||
===Notes=== | ===Notes=== | ||
− | {{feature test macro|__cpp_lib_unreachable}} | + | {{feature test macro|__cpp_lib_unreachable|std=C++23|value=202202L|{{tt|std::unreachable}}}} |
===Possible implementation=== | ===Possible implementation=== | ||
{{eq fun | {{eq fun | ||
− | + | |1= | |
− | [[noreturn]] inline void unreachable() { | + | [[noreturn]] inline void unreachable() |
− | + | { | |
− | + | // Uses compiler specific extensions if possible. | |
− | + | // Even if no extension is used, undefined behavior is still raised by | |
− | + | // an empty function body and the noreturn attribute. | |
+ | #if defined(_MSC_VER) && !defined(__clang__) // MSVC | ||
+ | __assume(false); | ||
+ | #else // GCC, Clang | ||
+ | __builtin_unreachable(); | ||
+ | #endif | ||
} | } | ||
}} | }} | ||
===Example=== | ===Example=== | ||
− | {{example|code= | + | {{example |
− | + | |code= | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
#include <cassert> | #include <cassert> | ||
#include <cstddef> | #include <cstddef> | ||
#include <cstdint> | #include <cstdint> | ||
#include <utility> | #include <utility> | ||
+ | #include <vector> | ||
struct Color { std::uint8_t r, g, b, a; }; | struct Color { std::uint8_t r, g, b, a; }; | ||
− | // Assume only | + | // Assume that only restricted set of texture caps is supported. |
void generate_texture(std::vector<Color>& tex, std::size_t xy) | void generate_texture(std::vector<Color>& tex, std::size_t xy) | ||
{ | { | ||
− | switch (xy) { | + | switch (xy) |
− | + | { | |
− | + | case 128: [[fallthrough]]; | |
− | + | case 256: [[fallthrough]]; | |
− | + | case 512: /* ... */ | |
− | + | tex.clear(); | |
− | + | tex.resize(xy * xy, Color{0, 0, 0, 0}); | |
− | + | break; | |
− | + | default: | |
+ | std::unreachable(); | ||
} | } | ||
} | } | ||
Line 55: | Line 60: | ||
generate_texture(tex, 128); // OK | generate_texture(tex, 128); // OK | ||
assert(tex.size() == 128 * 128); | assert(tex.size() == 128 * 128); | ||
− | + | generate_texture(tex, 32); // Results in undefined behavior | |
} | } | ||
|p=true | |p=true | ||
Line 61: | Line 66: | ||
Segmentation fault | Segmentation fault | ||
}} | }} | ||
+ | |||
+ | ===See also=== | ||
+ | {{dsc begin}} | ||
+ | {{dsc inc|cpp/language/attributes/dsc assume}} | ||
+ | {{dsc inc|cpp/memory/dsc assume_aligned}} | ||
+ | {{dsc see c|c/program/unreachable}} | ||
+ | {{dsc end}} | ||
===External Links=== | ===External Links=== | ||
− | + | {{elink begin}} | |
− | + | {{elink|num=1|[https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005funreachable GCC docs: {{tt|__builtin_unreachable}}]}} | |
− | + | {{elink|num=2|[https://clang.llvm.org/docs/LanguageExtensions.html#builtin-unreachable Clang docs: {{tt|__builtin_unreachable}}]}} | |
+ | {{elink|num=3|[https://docs.microsoft.com/en-us/cpp/intrinsics/assume MSVC docs: {{tt|__assume}}]}} | ||
+ | {{elink end}} | ||
{{langlinks|cs|de|es|fr|it|ja|ko|pl|pt|ru|zh}} | {{langlinks|cs|de|es|fr|it|ja|ko|pl|pt|ru|zh}} |
Latest revision as of 11:43, 9 September 2024
Defined in header <utility>
|
||
[[noreturn]] void unreachable(); |
(since C++23) | |
Invokes undefined behavior at a given point.
An implementation may use this to optimize impossible code branches away (typically, in optimized builds) or to trap them to prevent further execution (typically, in debug builds).
Contents |
[edit] Notes
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_lib_unreachable |
202202L | (C++23) | std::unreachable
|
[edit] Possible implementation
[[noreturn]] inline void unreachable() { // Uses compiler specific extensions if possible. // Even if no extension is used, undefined behavior is still raised by // an empty function body and the noreturn attribute. #if defined(_MSC_VER) && !defined(__clang__) // MSVC __assume(false); #else // GCC, Clang __builtin_unreachable(); #endif } |
[edit] Example
Run this code
#include <cassert> #include <cstddef> #include <cstdint> #include <utility> #include <vector> struct Color { std::uint8_t r, g, b, a; }; // Assume that only restricted set of texture caps is supported. void generate_texture(std::vector<Color>& tex, std::size_t xy) { switch (xy) { case 128: [[fallthrough]]; case 256: [[fallthrough]]; case 512: /* ... */ tex.clear(); tex.resize(xy * xy, Color{0, 0, 0, 0}); break; default: std::unreachable(); } } int main() { std::vector<Color> tex; generate_texture(tex, 128); // OK assert(tex.size() == 128 * 128); generate_texture(tex, 32); // Results in undefined behavior }
Possible output:
Segmentation fault
[edit] See also
[[assume(expression)]] (C++23)
|
specifies that the expression will always evaluate to true at a given point (attribute specifier) |
(C++20) |
informs the compiler that a pointer is aligned (function template) |
C documentation for unreachable
|
[edit] External Links
1. | GCC docs: __builtin_unreachable
|
2. | Clang docs: __builtin_unreachable
|
3. | MSVC docs: __assume
|