Live data from Hacker News

Three new utility functions in C++23

mariusbancila.ro

51–60 of 196 posts

Re: Three new utility functions in C++23

#51
post #43

Silly question from someone who hasn’t written C++ in 20 years and only very vaguely remembers it - if a code path is unreachable, why have the path at all? Is a default on a switch required? Is lack thereof a compiler warning or something? It’s been a very long time; I only ever seem to recall that kind of “all paths must be handled” from functional languages.

‘default’ is there by default anyway. This new feature allows to explicitly state that there isn’t one.

Re: Three new utility functions in C++23

#52

My 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…

[deleted]

Re: Three new utility functions in C++23

#53

My 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?

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.

Re: Three new utility functions in C++23

#54
post #43

Silly question from someone who hasn’t written C++ in 20 years and only very vaguely remembers it - if a code path is unreachable, why have the path at all? Is a default on a switch required? Is lack thereof a compiler warning or something? It’s been a very long time; I only ever seem to recall that kind of “all paths must be handled” from functional languages.

It can also improve codegen and is a building block of building an assume like macro to convey preconditions to the compiler and optimize potentially on that. The other is at the end of a function that can be guaranteed to never reach that point so that the compiler can know. Its a low level tool and shouldn’t be used without caution

Re: Three new utility functions in C++23

#55
post #43

Silly question from someone who hasn’t written C++ in 20 years and only very vaguely remembers it - if a code path is unreachable, why have the path at all? Is a default on a switch required? Is lack thereof a compiler warning or something? It’s been a very long time; I only ever seem to recall that kind of “all paths must be handled” from functional languages.

It can help both optimizations and static analysis. For example in the switch case in principle the compiler can avoid doing bound checks on the switch jump table. For static analysis it can help flags paths that can actually happen as erroneous.

Re: Three new utility functions in C++23

#56
post #53

Earlier 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?

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.

Re: Three new utility functions in C++23

#57
post #6

Hmm. How often do people actaully want to std::byteswap as opposed to "convert this value from native byte order to big-endian" or "convert this value from little-endian to native byte order"? i.e., the functions documented in https://man7.org/linux/man-pages/man3/endian.3.html (why oh why are they not also documented in the GNU C Library Manual...)

Yeah, for portable code you also need a function to tell you if you're on an architecture where you need to do a byteswap for the data you have. e.g. you know you have data in little-endian format - do you need to swap it to work with it natively? That depends. Maybe having something like convert_be() and convert_le(), one of which is a no-op and the other does the byteswap (depending on your arch) would be better. I…

Those are in as of c++20

Re: Three new utility functions in C++23

#58

Earlier quoted context omitted.

Yeah, for portable code you also need a function to tell you if you're on an architecture where you need to do a byteswap for the data you have. e.g. you know you have data in little-endian format - do you need to swap it to work with it natively? That depends. Maybe having something like convert_be() and convert_le(), one of which is a no-op and the other does the byteswap (depending on your arch) would be better. I…

I view it more as a platform-independent building block to be used by library authors. For instance, here's our suite of byte order macros that this will not simply replace: https://bloomberg.github.io/bde-resources/doxygen/bde_api_pr...

Yes, there is also std::endian::{big, small, native} that can be used to check if you need to byteswap or not. So a generic hton* is just:

   auto to_network_endian(auto std::integral value) {
      if constexpr (std::endian::native != std::endian::big) { 
          return std::byteswap(value); 
      } else { 
          return value; 
      }
   }
ntoh is left as an exercise :).

edit: in practice I think std::endian and std::byteswap is a compromise between those that wanted a simple {to,from}_network_endian and those that wanted strongly typed wrappers to prevent mixing object with distinct endianess (a-la boost::endian). As the commitee couldn't reach consensus, this is the compromise and you can build your own thing with these portable bits.

Re: Three new utility functions in C++23

#59
post #43

Silly question from someone who hasn’t written C++ in 20 years and only very vaguely remembers it - if a code path is unreachable, why have the path at all? Is a default on a switch required? Is lack thereof a compiler warning or something? It’s been a very long time; I only ever seem to recall that kind of “all paths must be handled” from functional languages.

Not C++ specific, but the example given - a default case that is not expected to ever be hit - is a "cover all bases" thing, to avoid undefined behaviour. Without the default case, what should happen? In the example given, it would just do nothing, but it would do so silently, which could lead to hours of developer time wasted trying to figure out why it doesn't do anything.

But I can imagine other use cases that are like "this is not supposed to happen" that can cause major issues like buffer overflows. Better to be more defensive and write code that basically says you are aware of code that shouldn't be reachable.

Re: Three new utility functions in C++23

#60
post #41

Why 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.

Backwards compatibility and a slow moving industry; adding more to a standardization process will only postpone the release.

More and more programming languages are moving to a more lightweight or scheduled release schema though, e.g. Java that had been stuck in limbo for nearly a decade due to design-by-committee and backwards compatibility concerns by major players.

Post reply on HN