Do you consider this a C++ language bug that you happen to be able to exploit? Or a necessary result of being able to combine several correctly behaving features?
It is part of both, the technique described is not the only way to reach a solution for the given problem (implementing a counter usable in constant-expressions).
In other words; if one sees this as a "bug" in the ISO C++ Standard, the "problem" is a lot deeper than friendly definitions (the technique used in the post).
C++ is a complex language, where many rules touch upon other, and with that it is not surprising that some rules can be bent to allow behavior which was perhaps never intended.
Future posts (probably after part 3) will address the philosophy of the "exploit", other techniques that boil down to doing the same thing, as well as proposed (ISO Standard) wording to "fix" the "problem" - if that is the path being walked.
I kind of hope they don't fix it. I could see this being as useful as the Boost Pre-processor Library. In fact I already know of a place where it would be useful. The Template Unit Test library requires (did require?) you to manually number your tests in sequence as template arguments. This const_expr counter could be used to not need to assign the numbers by hand.
This is absolutely insane. In the best possible sense of that word. I've always known I will never know C++ properly, as it is such a complex language. (Too complex I think.) I learned a few things from your insane stories. Thank you! Looking forward to being amazed more.
The underlying “paradox” seems to be that a constexpr is in spirit a compile-time constant, that testing whether certain things are defined is possible using such an expression, but that in C++ whether those things have in fact been defined yet changes during the course of compilation.
So, if you can control exactly when things become defined, for example by using clever template instantiation mechanics as shown here, you can potentially change the value of a constexpr during the course of compilation.
I could see this having some entertaining and perhaps useful possibilities for people who enjoy things like template metaprogramming. On the other hand, the robustness of the technique does seem to depend on being able to very tightly control those instantiation mechanics, which is a minefield already in C++, which I suspect makes this technique a little too clever for production use.
[Edit: Removed reference to this technique being like embedding a compile-time linear type system. That doesn’t seem to be quite the right analogy here; it’s more a system where you can generate unique new values but never return to values you had before once they have changed.]
This topic was discussed in Lenexa at last week's C++ standards meeting, and the direction the core working group was thinking was that this should be ill-formed, but is currently under specified. I would not rely on this ADL constexpr trick working for long (at least until CWG has had the chance to really pick apart the issue and change the wording to explicitly allow it).
I have been trying _very_ hard to get in contact with the folks that are discussing this approach; just preventing ADL constexpr tricks (through "friendly definitions") isn't enough.
I am still waiting for the relevant parties to reply to my emails, but an article explaining "everything" (and the different approaches (about 3 at the current time, in addition to "friendly definitions") will be published soon.
There is a lot of wording that has to be changed in order to prevent the semantics explained.
I apologize for being imprecise. We're aware it's more than just ADL or constexpr, but we had insufficient time to address it at this meeting. It's definitely on our radar, we flagged it as a high priority item.
I just submitted a request to join the reflector where I know this is being discussed; nonetheless, information will be published on http://b.atch.se as soon as I have had time to write the contents of new posts.
11 comments
[ 4.5 ms ] story [ 39.5 ms ] threadFeedback is more than welcome!
/Filip Roséen
In other words; if one sees this as a "bug" in the ISO C++ Standard, the "problem" is a lot deeper than friendly definitions (the technique used in the post).
C++ is a complex language, where many rules touch upon other, and with that it is not surprising that some rules can be bent to allow behavior which was perhaps never intended.
Future posts (probably after part 3) will address the philosophy of the "exploit", other techniques that boil down to doing the same thing, as well as proposed (ISO Standard) wording to "fix" the "problem" - if that is the path being walked.
The underlying “paradox” seems to be that a constexpr is in spirit a compile-time constant, that testing whether certain things are defined is possible using such an expression, but that in C++ whether those things have in fact been defined yet changes during the course of compilation.
So, if you can control exactly when things become defined, for example by using clever template instantiation mechanics as shown here, you can potentially change the value of a constexpr during the course of compilation.
I could see this having some entertaining and perhaps useful possibilities for people who enjoy things like template metaprogramming. On the other hand, the robustness of the technique does seem to depend on being able to very tightly control those instantiation mechanics, which is a minefield already in C++, which I suspect makes this technique a little too clever for production use.
[Edit: Removed reference to this technique being like embedding a compile-time linear type system. That doesn’t seem to be quite the right analogy here; it’s more a system where you can generate unique new values but never return to values you had before once they have changed.]
I am still waiting for the relevant parties to reply to my emails, but an article explaining "everything" (and the different approaches (about 3 at the current time, in addition to "friendly definitions") will be published soon.
There is a lot of wording that has to be changed in order to prevent the semantics explained.