Earlier quoted context omitted.
Directives are attached to functions, like abort() has the [[noreturn]] attribute, so compilers don't have to emit any code that would run after it returns, or save anything on the stack. std::unreachable() goes a step further, and tells the compiler that it doesn't even have to emit the call instructions or any instructions leading up to it.
Yeah obviously it's a compiler intrinsic. That's not what I or the person I was replying to was saying, and wasn't the relevant point. We were saying how else could you give the compiler an intrinsic, without a call of some kind? Like what other syntactic mechanism is there you can treat as an intrinsic in the compiler.
Three new utility functions in C++23
101–110 of 196 posts
Re: Three new utility functions in C++23
#102My first impression is that all three of these are clutter to an already very cluttered language ... 1.) Coming from embedded programming, I can see the utility of `std::unreachable`. But shouldn't this be a compiler directive? Or a standardized #pragma? Can someone more knowledgeable in C++ say whether using functions as markers is a common mechanism in std:: ? 2.)Maybe the example is bad here, as it doesn't even sa…
Is there syntax available in C++ to write some kind of instruction to the compiler which is not some kind of call? Even __builtin_trap is a call isn't it? What else could you attach a directive to?
Re: Three new utility functions in C++23
#103Earlier quoted context omitted.
Is there syntax available in C++ to write some kind of instruction to the compiler which is not some kind of call? Even __builtin_trap is a call isn't it? What else could you attach a directive to?
c++11 style attribute. There are already similar attributes [[unlikely]] and [[likely]] which can be attached to any statement. Having [[unreachable]] wouldn't be that surprising. C++23 also introduced [[assume(expr)]] which is basically conditional unreachable. I don't see a reason why standard committee couldn't have defined that [[assume(false)]] can be used for that purpose instead of new builtin. Either of the t…
Re: Three new utility functions in C++23
#104Why on earth are these in C++23 and not C++11? There are a ton of things that should’ve been standardized over a decade ago but only show up in C++20 or later. `std::span ` is a huge one. The mind boggles.
You can't just have some dude write a span.hpp and go "yep, that's going into my compiler v2" - not how standards work.
Re: Three new utility functions in C++23
#105My first impression is that all three of these are clutter to an already very cluttered language ... 1.) Coming from embedded programming, I can see the utility of `std::unreachable`. But shouldn't this be a compiler directive? Or a standardized #pragma? Can someone more knowledgeable in C++ say whether using functions as markers is a common mechanism in std:: ? 2.)Maybe the example is bad here, as it doesn't even sa…
1. It is a compiler defined function (`__builtin_unreachable()`), but the issue is that MSVC doesn't have it, so you need a different implementation per compiler [0]. Plus, if a new compiler shows up (besides MSVC/GCC/LLVM), you'd need to investigate what the correct way to express `__builtin_unreachable` is. From a compiler perspective, using a function makes the most sense, since that fits into the existing control…
They are still far from being the only game in town.
Re: Three new utility functions in C++23
#106My first impression is that all three of these are clutter to an already very cluttered language ... 1.) Coming from embedded programming, I can see the utility of `std::unreachable`. But shouldn't this be a compiler directive? Or a standardized #pragma? Can someone more knowledgeable in C++ say whether using functions as markers is a common mechanism in std:: ? 2.)Maybe the example is bad here, as it doesn't even sa…
1. It is a compiler defined function (`__builtin_unreachable()`), but the issue is that MSVC doesn't have it, so you need a different implementation per compiler [0]. Plus, if a new compiler shows up (besides MSVC/GCC/LLVM), you'd need to investigate what the correct way to express `__builtin_unreachable` is. From a compiler perspective, using a function makes the most sense, since that fits into the existing control…
This is wrong a lot of pragmas, I would even say most pragmas are not handled by preprocessor. Some examples: pragma pack, warning control, pragma GCC unroll, per function optimization setting changes, all the pragmas which 1:1 map to c++11 style attributes. None of that is handled by preprocessor, pragma once seems like rare one which is. Yes all of them are compiler specific, but handling compiler specific behavior is one of the main purpose of pragmas.
Re: Three new utility functions in C++23
#107Earlier quoted context omitted.
1. It is a compiler defined function (`__builtin_unreachable()`), but the issue is that MSVC doesn't have it, so you need a different implementation per compiler [0]. Plus, if a new compiler shows up (besides MSVC/GCC/LLVM), you'd need to investigate what the correct way to express `__builtin_unreachable` is. From a compiler perspective, using a function makes the most sense, since that fits into the existing control…
> Plus, if a new compiler shows up (besides MSVC/GCC/LLVM) They are still far from being the only game in town.
Re: Three new utility functions in C++23
#108Earlier quoted context omitted.
One thing people are missing is that you may need to use this to satisfy conditions that the compiler might encounter to emit a warning (or error if equivalent of -Werror is enabled). If you have strict warnings on, but no way to tell the compiler that a location should not be reachable, you wind up in situations where you are doing something like `assert(!"not reached!")` and it won't be enabled in all build types.…
For that abort() is just fine. Being UB, unreachable is more about optimizations .
> For example, without the __builtin_unreachable in the example below, the compiler assumes that the inline asm can fall through and prints a “function declared ‘noreturn’ should not return” warning.
void myabort(void) __attribute__((noreturn));
void myabort(void) {
asm("int3");
__builtin_unreachable();
}Re: Three new utility functions in C++23
#109I understand why it's there, but I do find it fun that when many people are trying to reduce undefined behaviour in their code, std::unreachable is literally defined as "this is undefined behaviour, use that to optimise". I suspect 99.9% of uses of std::unreachable would be better replaced by abort. (There will be those times when the code is correct and the optimisation gains are worth it -- but they will be rare).
The rational is better explained there :)
Most programmers will write an error message and halt execution flow (return EXIT_FAILURE, abort(), exit() or even an exception). The hint about assembler give cares about special (maybe optimized or machine specific) code or embedded stuff. And the second example refers explicitly to functions which do exit() and never return actually. The committee tidies up stuff. Something which compilers provide individually is becoming standard.
Re: Three new utility functions in C++23
#110Earlier quoted context omitted.
For that abort() is just fine. Being UB, unreachable is more about optimizations .
The literal example in the Clang documentation is not about optimization: > For example, without the __builtin_unreachable in the example below, the compiler assumes that the inline asm can fall through and prints a “function declared ‘noreturn’ should not return” warning. void myabort(void) __attribute__((noreturn)); void myabort(void) { asm("int3"); __builtin_unreachable(); }