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

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • 6
    It is very unpredicable, even for compilers. – Hannes Hauptmann Jul 23 '17 at 15:13
  • 1
    @HannesHauptmann Can you expand on that? It's the compiler's job to (sometimes) execute a constexpr function, not to predict what will happen when it does. – Sneftel Jul 23 '17 at 15:15
  • 1
    Beyond reading https://isocpp.org/files/papers/N3652.html , I guess you'll have to ask the standards committee (and/or the authors of the proposal), as far as a rationale goes. – Jesper Juhl Jul 23 '17 at 15:16
  • 1
    @Sneftel Not really an answer, but shouldn't we deprecate `goto` at a certain point? Especially with new language features introduced. – user0042 Jul 23 '17 at 15:17
  • 10
    @user0042 goto still has it's uses, it's a valid and needed construct – Sopel Jul 23 '17 at 15:20
  • @user0042 aaah, I dunno. AFAIK it doesn't cause compilers any real pain (though maybe it does here?), and given how widely known its evilness is, I'm not sure removing it would even improve coding practices that much. – Sneftel Jul 23 '17 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). – Jesper Juhl Jul 23 '17 at 15:21
  • @JesperJuhl Hah, I love that aside in the accepted changes section. "(But not goto, *Steve*.)" – Sneftel Jul 23 '17 at 15:22
  • @Sopel I don't know any case, where `goto` can't be replaced with some other control flow construct in c++. – user0042 Jul 23 '17 at 15:22
  • @Jesper Which existing code should get broken when using new features? – user0042 Jul 23 '17 at 15:23
  • 1
    @user0042 my point is that if you remove `goto` you potentially break a lot of legacy code. And legacy code is important and the *overwhelming majority* of code out there - breaking it is *not* cool. – Jesper Juhl Jul 23 '17 at 15:25
  • @Jesper I didn't say _remove it_, but deprecate `goto` in conjunction with new language features as asked in the OP. – user0042 Jul 23 '17 at 15:27
  • 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. – Matteo Italia Jul 23 '17 at 15:28
  • 17
    Could you guys stay on topic? This isn't the place for a 'goto pros & cons' discussion. – Andreas Jul 23 '17 at 15:29
  • @Matteo I prefer the `do { if(!cond) break; } while(false);` idiom to refactor deeply nested loops. – user0042 Jul 23 '17 at 15:30
  • 1
    @mrt I still believe everything said is still OT and related to the question. – user0042 Jul 23 '17 at 15:34
  • 1
    @HannesHauptmann Which C or C++ construct is simpler, or more predictable than `goto`? (Beside the null statement.) – curiousguy Jan 17 '19 at 20:40

2 Answers2

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!

Barry
  • 286,269
  • 29
  • 621
  • 977
  • 4
    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]? – Sneftel Jul 23 '17 at 19:58
  • @T.C. Thanks! You'd think I would've found the paper literally entitled "constexpr goto"... – Barry Jul 24 '17 at 03:01
  • @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 Jan 17 '19 at 20:52
  • @curiousguy Are you going to write a paper suggesting constexpr goto? – Barry Jan 17 '19 at 20:56
  • @Barry If I wasn't desperate with the attempt at purity and arrogance of the committee, I would. – curiousguy Jan 17 '19 at 21:14
  • @curiousguy I mean, writing snarky comments on the internet might make you feel better about yourself, but it's not actually productive? I'm not sure what you're trying to accomplish here exactly. – Barry Jan 17 '19 at 21:16
  • @Barry I have tried to point out some undeniable issues directly while I was in the committee and was ignored because one person said the issue didn't exist and that was enough. – curiousguy Jan 17 '19 at 21:17
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.

jszpilewski
  • 1,632
  • 1
  • 21
  • 19
  • 3
    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 Jul 23 '17 at 19:30
  • @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. – jszpilewski Jul 23 '17 at 20:21
  • 1
    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. – edmz Jul 23 '17 at 20:49
  • 3
    @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. – Nicol Bolas Jul 24 '17 at 00:44
  • @NicolBolas The fiasco happened because MS opposed `export`, based on hearsay and absurd claims. – curiousguy Jan 17 '19 at 20:55
  • @NicolBolas Cfront didn't even support `export`, it had exported templates by default. I believe that GCC had a way to separately compile templates, somehow. And you're the one spreading misinformation, in the form of MS propaganda, exactly like I said. Herb's paper was extremely badly received in the committee, his behavior was seen as unprofessional. It's essentially hearsay and out of context quotes. – curiousguy Jan 17 '19 at 21:52
  • @NicolBolas You provided evidence that it's indeed MS a based document that caused the change, that was extremely badly received **after it was uncovered as biased, unfounded propaganda**. I know how it was perceived because I actually talked to these people. Did you? Also "the context of the instantiation is effectively unpredictable": I have no idea what they are getting it. – curiousguy Jan 17 '19 at 21:59
  • @curiousguy: So where is your proof that "it was uncovered as biased, unfounded propaganda?" Show me statements by the people quoted that they were taken out of context. Show me statements that they genuinely think `export` was a good, well-thought-out feature that required reasonable effort to implement in C++. Show me evidence of this GCC feature that worked like `export`. Show me something more than your words. – Nicol Bolas Jan 17 '19 at 22:01
  • @NicolBolas All Herb provided is out of context vague quotes of people who claimed later they didn't meant that, and hearsay re: what experts believe, which experts said they never believed. I know what I'm talking about. – curiousguy Jan 17 '19 at 22:02
  • @curiousguy: Then prove it by showing me evidence that they never believed these things. – Nicol Bolas Jan 17 '19 at 22:03
  • @NicolBolas Do you need evidence that Cfront essentially had exported templates? Anyway, I don't care about impressing you. I just wanted to correct the misinformation you are propagating, period. Just ask real experts in a face to face conversation. – curiousguy Jan 17 '19 at 22:03
  • @NicolBolas Who? What are the names of these people? It's a silly conversation. I'm done. – curiousguy Jan 17 '19 at 22:04
  • @curiousguy: "*What are the names of these people?*" The names are listed in the paper I cited, right next to their quotations. Oh right, that's MS propaganda and therefore must be ignored. – Nicol Bolas Jan 17 '19 at 22:05
  • @NicolBolas Cite these names. – curiousguy Jan 17 '19 at 22:06
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/186889/discussion-between-nicol-bolas-and-curiousguy). – Nicol Bolas Jan 17 '19 at 22:06