
Non-constant constant-expressions in C++ - refp
http://b.atch.se/posts/non-constant-constant-expressions/
======
Negitivefrags
In this comment thread are a bunch of people pretending that just because
something can be done means that all C++ programmers will actually do it.

If someone writes a "here is a cool thing" article for another language
involving arbitrary obscure details they are praised with "cool hack". If the
language is C++ then out comes all the rants about how C++ is inherently
unmaintainable because of "this kind of thing".

Why do people react to C++ this way and not other languages?

The reason this happens is because the only thing all the other comments in
this thread are really saying is "Preconceptions about C++ confirmed!". It's
easy to reap the karma with such comments.

~~~
yoklov
> Why do people react to C++ this way and not other languages?

Probably because stuff like boost::mpl (and so many awful half-implementations
of it) exists.

Sadly, if there's a perceived use for a C++ feature, it will be used, no
matter how convoluted it is. This is a specific case of a general method for
adding state to constexpr, which might be considered useful... I wouldn't be
shocked to see this used in the future.

------
sz4kerto
Interestingly, this is because -- after reasonable amount of C++, C#, Java
coding I have just settled with Clojure (or Lisp in general). I really enjoyed
writing clever C++ template stuff like class hierarchy generators and so on
until I became old enough to think that good!=clever, good==maintainable&&it
works.

Too much syntax and cleverness is bad for the industry as usually it attracts
a lot of smart people who end up writing C++ (or Scala) -- but the problem is
that they use a set of patterns+language subset that is unique to the
team/company. Therefore knowing C++ does not mean you can just start at a
company using C++, you have to learn their way.

Notable exceptions are Java and C#. Java is so simple and verbose that you
can't write unreadable code unless you're really evil, it's a shame that the
complexity and cleverness is moved to the frameworks (there aren't many "Java
programmers", most of them are Spring, etc. specialists). C# works well
because MS dictates the patterns (and those patters are usually quite good)
while the language itself is very readable and intuitive, without crazy rules.

And there's Lisp/Clojure where there are only a handful simple rules, and
cleverness is usually local, e.g. macros or tricky 'functional' data
manipulation stuff; but for me that 'local' cleverness is the most
understandable.

~~~
evincarofautumn
I find it very difficult to read Java code because it tends to be so long-
winded and many-layered.

~~~
userbinator
Java is easy to read at the "micro" level, i.e. the bodies of methods usually
don't contain much code; but I think that is precisely what makes it hard to
understand at the macro/system level, because that small amount of code
depends on a much larger amount throughout the rest of the system, spread
across multiple files in different deeply-nested directories. That's when you
have to start following chains of method calls, object creations, and class
hierarchies.

------
Someone
Easier (and bending the rules a bit):

    
    
      #include <iostream>
      
      constexpr int f(int line)
      {
          return line;
      }
      
      #define f() f(__LINE__)
      
      int main(int argc, const char * argv[]) {
          constexpr int x = f();
          constexpr int y = f();
          
          std::cout << "x = " << x << "; y = " << y;
          return EXIT_SUCCESS;
      }
    

Also, I don't think the language designers required

 _" This lack of dependency must inherently mean that it will yield the same
value upon each invocation having the same set of arguments"_

to be true.
[http://en.cppreference.com/w/cpp/language/constexpr](http://en.cppreference.com/w/cpp/language/constexpr)
only states:

 _" The constexpr specifier declares that it is possible to evaluate the value
of the function or variable at compile time."_

The draft of the C++ standard on my system states that as follows:

 _" Certain contexts require expressions that satisfy additional requirements
as detailed in this sub-clause. Such expressions are called constant
expressions. [ Note: Those expressions can be evaluated during translation. —
end note ]"_

~~~
refp
> "This lack of dependency must inherently mean that it will yield the same
> value upon each invocation having the same set of arguments"

That quote was written in a "this is what most of us used to think" sort of
way, it was never intended to be read literally - though maybe I should
clearify the intent.

I certainly agree with your post, and your little hack is very cute; +1! :-)

------
barrkel
Articles like this are one of the reasons I don't profess to know C++ well. I
know almost all of the features in isolation, and many in combination, but new
combinations are being discovered with novel and surprising effects, like this
article demonstrates.

This is not a good advertisement for C++. It would have been much healthier to
not have had such a powerful and under-researched template instantiation
mechanism, and instead have a genuine compile-time macro language. It's hard
to see a way back though. Everything added - like constexpr functions - to
make compile-time execution more sane, can be put back into the mix to
complect things even further.

~~~
MaulingMonkey
> Articles like this are one of the reasons I don't profess to know C++ well.

...any why I profess _nobody_ knows C++ well, even those on the standards
committee ;)

------
halayli
This post demonstrates the problem in C++ community. Trying to do smart wacky
things that involves understanding so many C++ rules and aligning them with
the moons to figure out what is going on and then just assume that others can
easily maintain it.

It intimidates a lot of newcomers and leaves a bad taste. And then we wonder
why so many people hate the language.

~~~
brandonbloom
This post also demonstrates the importance of exposing the powerful
fundamentals. People are going to do crazy things anyway, so you might as well
offer those primitives rather than force people to contort the language to
emulate them. This means intentionally designing tractable components rather
than accidentally encouraging intractable abuse.

~~~
yoklov
Agreed. None of this would be an issue with good support for normal compile-
time metaprogramming, in the same language that the rest of the code is in,
without restrictions (or, with as few restrictions as is possible).

But thats obviously too much, at the very least, I'd want the language
designers to understand the implications of the features you add when you add
them. You'd think the C++ standards committee would have learned their lesson,
after _accidentally making templates turing complete_.

Even if templates are a great feature (and this is far from a universal
opinion), that just means they got lucky.

------
chombier
So basically, this means c++ template meta-programming is no longer pure (i.e.
side-effects can happen during meta-programs) right ?

If so, this is quite big news, similar to when people realised the extent to
which SFINAE could be abused. Not exactly sure this is a good thing though.

Ironically, I think some of Stroustrup's goals for c++11/14 were to lower the
need for complex template wizardry... Well, now we will have it complex AND
stateful !

