
C++ : if constexpr isn't broken - Bl4ckb0ne
https://brevzin.github.io/c++/2019/01/15/if-constexpr-isnt-broken/
======
roywiggins
"a somewhat more awkward and uglier, yet slightly more correct way... all the
functionality is right there. We’re not missing anything" might as well be
C++'s motto :)

~~~
aassddffasdf
"The amount of things you have to know in C++ is arguably a bit larger."

Arguably, lol.

~~~
nivexous
In Bitcoin SV, there is a saying "devs gotta dev" to refer to the mass of
crypto developers that add unnecessary complexity to their coins to solve
minor or even nonexistant problems while not seeing the bigger (usually
economic) picture. Everyone wants to make their mark on the space and there
aren't enough leaders to direct the energy. C++ looks to be doing the same and
not able to see the impact this will have on adoption. Oh well. I personally
moved from C++ to Rust last year and haven't looked back.

~~~
neutronicus
I disagree - I work in high-performance computing and I think in our case the
complexity of C++ is actually mirroring that of the problem domain. Nothing
else gives us the level of abstraction that C++ does, _while still offering
convenient ways to specify low-level performance semantics_.

I think for a while Fortran was pulling ahead for large-scale numerical
computing, but the mess of different options for parallelism (and also I think
in our case a profileration of algorithm choices that made not just
polymorphism but the explicit distinction between polymorphism and templates
more important for code architecture) have brought C++ back into the
limelight.

I know that some competitors in our space have a Fortran codebase and they
essentially had to hack together C++ Templates as part of their build process
(i.e. pre-process a template file and generate multiple sources which are then
compiled).

~~~
SamReidHughes
Looking at some C++ extension proposals, many are definitely a case of "devs
gotta dev." Fortunately most of these don't have a chance in hell of making it
in.

~~~
VHRanger
Yeah Stroustrup put his foot down this year on whacky proposals.

------
JabavuAdams
I used to be a C++ guy from the early 90s 'till about 2010. Every few months,
I think "I should really learn the new C++ hotness", and then I read something
like this. It's like a bunch of priests arguing about how best to fit a bunch
of ugly angels on a pointless pin. It just feels so pointless.

If you must use C++, just use another language to generate the C++. All this
template mumbo jumbo. Who says your meta-programming language has to be the
same as your target language?

I used to spend some time looking for the perfect vector (as in linear-
algebra) library. Templatized for vector dimension, data-type, blah blah blah.
Dude, just use Python to generate it. Duplication doesn't violate DRY if the
duplication is generated from a single higher-level source.

Doing meta-programming in C++ is a really limited way of thinking.

~~~
nealabq
> _fit a bunch of ugly angels on a pointless pin. It just feels so pointless._

A pointless pin would indeed be pointless.

------
mattnewport
I had similar thoughts when looking through the slides for Andrei's talk. A
main argument in favor of static if over the mechanisms C++ offers to do the
same things seems to be familiarity of if statements but having scope not be
respected is such an unintuitive difference for anyone with experience in
curly braces languages that it seems like a net loss in clarity to me. It
looks more like using macros for conditional compilation.

Overuse of if statements is generally something of a code smell and tends to
make code harder to follow. To my taste the C++ way of doing things is
generally preferable as a result even if more verbose. Given this is probably
somewhat a matter of taste it is hard to justify changing C++ to match the D
way IMO.

------
mark-r
Why is it every time I see a new article about C++ features my eyes glaze
over? Am I just getting old, or has C++ jumped the shark?

~~~
dasloop
Probably because you are used to the paralysed C++ pre C++11. Nothing happens
for years and now we have new functionalities every three years supported by
all major compilers. But, also, many new functionalities are not for global
consumption. The audience of many meta programming functionalities are library
developers for example.

~~~
jupp0r
Isn't every developer in a non-trivial software project a library developer?
As soon as you have a common piece of functionality you want to reuse - that's
a library.

~~~
MichaelSalib
I think that's dependent on language culture. Because the C++ community
doesn't take language simplicity or comprehensibility seriously, there are
lots of C++ developers who can't use or reason about surprisingly large parts
of the language. So the community has rallied around the notion that "library"
developers need to understand everything and that most developers will just
glue together bits that the library devs made.

I mean, how many C++ developers actually write serious template code? How many
of them could reliably explain what the keywords in post do?

The idea that every developer is a library author (or the lisp extension that
every developer is a language author) is common in many other language
communities but it relies on the community working hard to make mastery of the
language feasible for lots of people. The C++ community never bought into that
notion; they inherited a very stratified class structure from Bell Labs.

~~~
gumby
>... the C++ community doesn't take language simplicity or comprehensibility
seriously...

I think this is an unreasonable assertion and not borne our by a read of the
committee discussions.

~~~
MichaelSalib
To clarify: of course they like simplicity when it costs nothing. But they
consistently value other goods over simplicity.

For example: maintaining backwards compatibility. The community believes that
it is more important that 20 year old C++ code run unmodified than that the
language should be simplified. There's lots of stuff you could do to simplify
the language but options dry up in a world where 20 year old code must be able
to run unmodified.

So sure, the committee talks a lot about simplicity, but it isn't willing to
sacrifice much.

Don't get me wrong: I'm glad that finally, in 2020, C++ will be almost but not
quite as good as Common Lisp was at metaprogramming back in 1982. But it
remains the case that eval-when and defmacro are both more powerful and
dramatically simpler than anything the C++ committee has ever considered.

~~~
mattnewport
Two other goals for C++ are 'zero-cost abstractions' and 'leaving no room for
a lower level language'. It does better on both of these goals than Common
Lisp and they are important reasons for its popularity (along with backwards
compatibility and easy interop with C APIs).

~~~
MichaelSalib
Zero-cost abstractions only exist in a world where you don't highly value
language simplicity and comprehensibility.

Simplicity and comprehensibility were things the committee had to give up in
order to pretend they had "zero-cost" abstractions. Nothing in life comes
free: everything, including all abstractions, comes at some cost.

~~~
steveklabnik
> Nothing in life comes free: everything, including all abstractions, comes at
> some cost.

Yes. As a slogan, it is imprecise. But it's always been talking about a very
specific kind of cost: runtime costs. You're 100% right about there always
being some kind of cost, but the slogan doesn't disagree with you.

(Some prefer "zero-overhead principle" instead to make this a bit more clear.)

~~~
MichaelSalib
(1) I love your writing.

(2) Even reducing it to runtime costs, it seems a bit nonsensical. Are C++
exceptions a zero cost abstraction? All the googlers I argued with about them
would insist that they have unacceptably high runtime costs.

OK, but templates are surely zero (runtime) cost abstractions, right? Unless
you start to worry about duplicate code blowing out your instruction cache but
if that's a problem, no profiler in the world will ever be able to tell you,
so I guess you'll never know just how costly the abstraction is, so you might
as well continue believing it is zero...?

~~~
mattnewport
Zero cost abstraction is not the same thing as a free lunch. It's a goal that
using the abstraction will have no runtime cost relative to implementing the
same or equivalent functionality manually. It goes hand in hand in C++ with
the "don't pay for what you don't use" principle (again talking about runtime
performance cost).

When it comes to exceptions, it's generally true on x64 that you don't pay for
what you don't use (there's no performance penalty to exception handling if
you don't throw) although that hasn't always been true for all platforms and
implementations. It's also generally true that you couldn't implement that
kind of non local flow control more efficiently yourself, although the value
of that guarantee is a little questionable with exception handling.

I'd argue that no language has a really good story for error handling. It's
kind of tragic that we have yet to find a good way to deal with errors as an
industry IMO. The most promising possible direction I've seen is in some of
the possible future extensions to C++ - it's widely recognized as an area for
improvement.

Template code bloat is another case of not imposing more cost than if you
implemented it yourself and you have pretty good mechanisms in C++ for
managing the tradeoffs.

~~~
MichaelSalib
> When it comes to exceptions, it's generally true on x64 that you don't pay
> for what you don't use (there's no performance penalty to exception handling
> if you don't throw) although that hasn't always been true for all platforms
> and implementations. It's also generally true that you couldn't implement
> that kind of non local flow control more efficiently yourself, although the
> value of that guarantee is a little questionable with exception handling.

I'm inclined to agree with you but just about everyone at Google says the
opposite and most C++ shops I've seen agree with them. I've made this argument
and lost repeatedly. So, it seems like the community can't even agree on which
abstractions are zero cost (or maybe whether some zero cost abstractions are
actually zero cost?). To the extent that the community itself has no consensus
about these things, maybe they're not a marketing slogan that's helpful to
use.

------
wyldfire
Slides from Alexandrescu's referenced talk [1].

[1]
[http://erdani.com/MeetingC++2018Keynote.pdf](http://erdani.com/MeetingC++2018Keynote.pdf)

------
cjhanks
I agree with this blog writer. Allowing typedefs to cross static if boundaries
would be a major change to the way I read code. Unless there's a more
substantive example demonstrating why using the existing metaprogramming is
insufficient, its benefits are imo outweighed by its cost.

~~~
renox
Well you already have to remember that 'if' introduces a scope but '#if'
doesn't..

~~~
cjhanks
I guess that's true. But I can't remember the last time I have used `#if`
aside from header guards and optimization paths. So they _do_ exist, but I
almost never do this.

------
greesil
I think I just got used to C++11. What is this dark magic?

~~~
felixguendling
If you refer to `if constexpr`: There is no dark magic. Most of it is already
possible with C++11 meta programming (i.e. with std::enable_if [0]). However,
it's much more readable now (and it's more fun to write :D). I think we're on
a good way that compile time programming will be more easily accessible.

[0]
[https://en.cppreference.com/w/cpp/types/enable_if](https://en.cppreference.com/w/cpp/types/enable_if)

------
choeger
Oh my. If only C++ would have used proper macros from the start...

~~~
gumby
I discussed this once with Stroustrup. He mourned that the word "macro" had
been "polluted" (his word, though I completely agreed) by the preprocessor and
said "templates was the best we could do within the constraints of C".

This was in the mid 90s and things are a lot better these days but still, I
had better macro support writing Lisp in the 1970s.

~~~
choeger
I am ready to believe that hygienic macros would have been difficult, but just
using lisp macros should have been straightforward. Tbh, I think that
templates were an adhoc, amateurish design decision.

~~~
gumby
A lot of the arcanity in templates is the arcane C syntax they are shackled
to. I wouldn’t call it ad HPC.

Lisp is so much easier. But current C++ is surprisingly expressive and
generates pretty good production code. Instrumenting your Lisp with a lot of
type declaration is pretty messy too.

