On Mon, Jan 6, 2025 at 11:54 AM Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
On Mon, 6 Jan 2025 at 18:20, Arthur O'Dwyer via Std-Proposals
<std-proposals@lists.isocpp.org> wrote:
> More background on the `goto` thing: C++ has supported loops, break, continue, and (more to the point) `switch` in constexpr evaluation mode since C++14. C++ has never supported `goto` in constexpr. As Richard Hodges said, this isn't for any deep technical reason; it's because "goto is bad".

That is not correct. Implementation vendors have reported that
supporting goto in their constexpr interpreters is a significant
additional
burden, and one unlike the burden required for supporting switch-case
or break/continue.

Has any vendor said so publicly? Has any vendor said so in the minutes? Do the rumors indicate which vendor(s) allegedly said this — like, is this supposed to be a problem with Clang, GCC, MSVC, EDG, or someone else? (I could imagine someone implementing constexpr goto in, say, Clang, just to be told post-facto "Well sure it's possible in Clang, but it's supposed to be hard for another compiler." Having the list of who-thinks-it's-hard up front would make it easier to construct a proof that it's not.)

All I'm seeing publicly on the topic is the statements from Barry in 2017 and from Ville in 2015, which both come down on the side of "it's not technologically hard, it's just a stylistic diktat."
P2242, which was adopted for C++23 and lifted C++14's ban on `goto`'s appearing lexically within a constexpr function, sadly doesn't talk about either (1) whether there are technical difficulties with `goto` nor (2) why `goto` was so totally banned to begin with.

There's little technologically unusual about a `goto` that's not already unusual about a `switch` (which can go to an arbitrary `case` label, possibly in a nested scope, just like `goto`). It's just that `goto` can go lexically backwards (a trait it shares with `break` and `continue`) as well as lexically forwards.
Meanwhile, `continue`-with-label (the very feature C adopted in N3355) allows you to actually build constexpr `goto` out of a `switch` state-machine. So if some vendor does have a problem with constexpr `goto`, then that vendor will probably also have the same problem with constexpr labeled loops — no matter what syntax is adopted for them.

[UNTESTED CODE]

#define PREAMBLE(lbl) enum { INITIAL, LABEL_##lbl } state = INITIAL; \
TOP: while (true) { switch (state) { case INITIAL:;
#define GOTO(lbl) state = LABEL_##lbl; continue TOP;
#define LABEL(lbl) case LABEL_##lbl:;
#define POSTAMBLE return; }}

constexpr auto get_first_line(const std::string& string)
{
PREAMBLE(past_for)
std::string first_line{};
for (const auto character : string)
switch (character)
{
case '\n':
GOTO(past_for) // breaks from 'range-for loop'
default:
first_line += character;
break;
}
LABEL(past_for)
return first_line;
}
static_assert(get_first_line("Hello\nworld!") == "Hello");