Jason Merrill <[email protected]> writes: > I think this choice could use more explanation of its rationale. IIUC > this is e.g. to allow quals | TYPE_QUAL_CONST but not quals1 | quals2 > where quals2 happens to contain only TYPE_QUAL_CONST?
Yes. Firstly, because quals2 cannot lack an address space qualifier (the syntactic lack of an address space qualifier just means that the object is qualified with the generic address space), so it never truly contains only TYPE_QUAL_CONST if it is a qualifier_set. Second, for address spaces in particular, it isn't always clear what the correct way to take the union of them is. If two address spaces are different but overlapping, which one do we pick, if any? If one is generic and the other not, do we always want to pick the latter (as is the case with qualifiers on type parameters, for instance, or when qualifying declarations that use type aliases)? What if they're fully disjoint? Usually, that's a cause to issue a diagnostic; with operator| we can't pass something like COMPLAIN as an argument. Third, if we permit that check to become a runtime check, then we do not get a (GCC-build-time) diagnostic if we fail to reckon with the address space component, and the goal is precisely to require address spaces to be handled, to prevent bugs caused by forgetting to do so (such as the examples I gave). None of those concerns apply if we're dealing with at most one address space and, ergo, at most one full qualifier_set, with the other operands(s) being plain cv_qualifiers: there's at most one address space involved so there's no question about which one to pick, it is clear what the union of two plain sets (in this case of cv_qualifiers) is, and the set union operation can never fail so there's never a diagnostic to be had. Note that languages that explicitly do not support address spaces can fit in this arrangement fairly easily. Like G++, they can provide their own version of TYPE_QUALS (called cp_type_quals in G++), and make it return cv_qualifier, and have it assert that there's no address space. Then, none of their code would stumble upon a qualifier set set, ever, and all the functions that would take a qualifier set can also accept a cv_qualifier (either through an overload as in this version or, if we switch qualifier_set to be a struct, through an implicit conversion constructor). Indeed, this is pretty much what I intend to do with the existing frontends to convert them. Similar to G++, this also gives them a "migration path" in the event that they *do* want address space support at some point. If they alter their LANG_type_quals to return a qualifier_set, suddenly, every place where they forget to deal with the address space becomes a compile-time error. > Maybe std::tie would be a useful substitute for structured bindings? Yeah, that could work, but the verbosity may not pay off in the end. The idea I had with that is to require that the user does something like: auto [cv, as] = qual_set; ... when dealing with qualifier sets. This forces the user to reckon with there being CV-qualifiers and an address space in the qualifier set, and it means that, if qualifier sets were to gain some third component (that, similar to address spaces, can't be added as a present/absent qualifier to 'cv'), each place that inspects the components of a qualifier_set would break and require being updated, whereas, if the user is just doing: auto cv = qual_set.cv; auto as = qual_set.av; ... adding a new component means that, silently, all the places which need to deal with the qualifier sets component-by-component go out of date. And, of course, it is not an error for the user to consult just one of the two members (whereas the user would explicitly need to throw away the hypothetical third one with structured bindings). The reason I reckon it's probably not worth it to use std::tie for this is because, by my estimate, it is unlikely that we'll get a new qualifier similar in fashion to address spaces. It seems more likely that, if there ever do come about any new qualifiers, they're similar to CVR; either absent or present. -- Arsen Arsenović
signature.asc
Description: PGP signature
