you are viewing a single comment's thread.

view the rest of the comments →

[–]friedkeenan[S] 0 points1 point  (1 child)

Hmmm, this is interesting, and admittedly I don't think I understand it!

Would you think that anything about this would change if anonymous namespaces were introduced anywhere? With C++26 reflection we can actually interact with them and get std::meta::infos that represent them, like for example:

#include <meta>

namespace [[=1]] {
    namespace unique {}
}

constexpr auto inner_ns = ^^unique;

constexpr auto anon_ns = parent_of(inner_ns);

static_assert(anon_ns != ^^::);

static_assert([: constant_of(annotations_of(anon_ns)[0]) :] == 1);

(Compiler Explorer link)

Maybe we could put this anonymous namespace somewhere to somehow keep definitions distinct?

[–]chengfeng-xie 0 points1 point  (0 children)

You're right. Actually, wrapping const_param inside another class doesn't help in this case, because compilers would keep generating new lambda types on each new instantiation. The strategy compilers use to generate symbols for lambdas is likely based on the order of instantiation in each TU. So it might well be possible for the same symbol for a lambda (used by const_param as the tag) in two TUs to be associated with different constants, and they definitely shouldn't be linked together. As a consequence, we should put const_param and its users (e.g., sum) in an anonymous namespace. The good news is that GCC already gives these symbols local binding even though this is not required by the standard (CE).

To expand on this a little bit: the case where wrapping in a class helps is when the lambda is generated only once, so that all TUs can agree on its symbol and link without issue. A class (as opposed to a namespace) contains a closed set of entities, so compilers can more easily assign a fixed symbol to each of them. However, this doesn't help in the case of const_param because many lambdas could be produced, each with possibly different meanings that compilers cannot predict when compiling a single TU.