26

C++14 has rules for what you can and can't do in a constexpr function. Some of them (no asm, no static variables) seem pretty reasonable. But the Standard also disallows goto in constexpr functions, even while it allows other control flow mechanisms.
What's the reasoning behind this distinction?
I thought we were past "goto is hard for compilers".

17
  • 6
    It is very unpredicable, even for compilers. Commented Jul 23, 2017 at 15:13
  • 10
    @user0042 goto still has it's uses, it's a valid and needed construct Commented Jul 23, 2017 at 15:20
  • 4
    @user0042 I don't think so. The amount of code you'd break is potentially enormous. Besides, goto does have its rare uses - like breaking out of multiple layers of a deeply nested loop. My belief is that goto is not a bad construct as such - you should just be very, very careful where you employ it (and usually you shouldn't). Commented Jul 23, 2017 at 15:21
  • 7
    @user0042: the Böhm-Jacopini theorem tells you that you can always replace goto, but at what price? A well placed goto for breaking out of a deeply nested loop or for C-style error cleanup is typically way clearer that the structured-programming workarounds. Commented Jul 23, 2017 at 15:28
  • 18
    Could you guys stay on topic? This isn't the place for a 'goto pros & cons' discussion. Commented Jul 23, 2017 at 15:29

2 Answers 2

21

My understanding is there was a desire to get relaxed constexpr semantics in C++14. A lot of the restrictions that were relaxed were straightforward, but some were more controversial or difficult or [insert adjective of your choice here]. Rather than hold up relaxed constexpr just for the ability to use goto, it was decided to just publish the main changes and hold off on the rest. This seems like a pretty sound choice, since constexpr in C++14 is far more powerful than constexpr in C++11, and not being able to use goto is a fairly minor absence, all things considered.

That said, there certainly exists the view that having goto in constexpr contexts is both useful and possible. Indeed, the initial proposal for relaxing constexpr allowed it. So maybe all it takes is somebody that wants it to write a proposal to add it. That somebody could be you! was apparently Ville Voutilainen two years ago in N4472, which featured the quite-relevant-to-this-question paragraph of:

There is unsubstantiated hearsay according to which banning goto in constant expressions is more for taste reasons than technical reasons, meaning that supporting goto in constant expressions isn't particularly hard to implement. I can't say whether that's correct for implementations in general.

The paper had mixed reception, but now that we have constexpr lambdas, maybe it needs to be revisited. And that somebody could be you!

Sign up to request clarification or add additional context in comments.

7 Comments

Sure, but at some point someone had to say "okay, for-loops are fine, but there's a problem with general goto". Why the bifurcation of treatment? What would make goto any more controversial, or difficult, or [other adjective]?
@T.C. Thanks! You'd think I would've found the paper literally entitled "constexpr goto"...
@Barry C++11 constexpr follow the macro like expansion of function calls. They are constant expressions if such expanded expressions are. There is no such logic for banning goto while allow mutation and loops, which obviously as least as difficult to implement. It's political correctness, period.
@curiousguy Are you going to write a paper suggesting constexpr goto?
@Barry If I wasn't desperate with the attempt at purity and arrogance of the committee, I would.
|
0

constexpr is expected to be evaluated by the front-end of the compiler in some pseudo-interpreted mode or on the abstract syntax tree built in a single pass before any executable code is generated. We know that goto may jump to some part at the end of the function which was not evaluated yet. Hence properly connecting calling and executing goto would force building AST in several passes and jumping out of order between nodes in a tree is still a messy operation that could break some state. So such a construction is not worth the trouble.

15 Comments

How would it complicate building the AST? Surely the AST for the entire translation unit would be built before the compiler even started thinking about constexpr evaluation. After all, that evaluation can't affect the parse.
@Sneftel The time when compiler evaluates the value of a constexpr is implementation dependent (it just must be done in in the front-end phase) but it will be much simpler to do if the AST is a basic one with an obvious evaluation order and without jumps between nodes.
C++ is an abstract language and whether its features are "easy" to implement or not is completely outside standard's concern. Exceptions, for instance, are not easy to implement yet they're in the language.
@black: "whether its features are "easy" to implement or not is completely outside standard's concern." No, it isn't. The standards committee frequently considers whether the implementation costs of implementing a particular feature are worth the gain to users for that feature. This is one reason the old C++0x Concepts died. And the lack of this consideration is why the C++98 export fiasco happened.
@NicolBolas The fiasco happened because MS opposed export, based on hearsay and absurd claims.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.