Hi Arthur,Thanks for your thoughtful and detailed response, and even taking the time to make Godbolt examples. I'm the co-author of P3132.I seems I misunderstood some things. Also, I think compilers might have grown more tolerant of other compilers' attributes since last I checked? Here are some thoughts:Accepting attributesWe compile with warnings as errors on all projects. So custom attributes always triggering a warning is an issue. If we turn off the warning, typos such as [[no_unoque_addriss]] won't get caught. I was wishing for anything with a custom namespace to be accepted silently, while standard attributes are still validated. So what are we to do? File bugs against every single compiler despite the fact they already standardized on this behavior for some reason? Seems like a tall order.Since all compilers act like this, I assumed it was standard-mandated (and my attempts at deciphering the standard didn't seem to contradict this).Is the standard really unable to enforce that compilers should not emit a warning in a given situation? In some situation it says that "implementations are encouraged to emit a warning". So it seems to me it could say "implementations are discouraged from emitting a warning" whenever an attribute with a custom prefix is detected.But perhaps a more elegant solution to coax things in the right direction would be to allow declaration of custom attributes. For now, this declaration would do nothing, but down the line it could be associated with a custom attribute implementation in C++ code.This way it'd be more natural for the compiler to accept your attributes, and you'd get typo protection.Now to come up with some syntax that doesn't involve adding a new keyword to the language... oh boy. I suppose claiming the attribute [[attribute]] to do this would make some modicum of sense.Strawman syntax:[[attribute]] [[myCompany::property]]; // declaration of a new attributeclass [[myCompany::property]] MyClass {}; // compiler expected to accept this without complainingclass [[Random::attribute]] AnotherClass {}; //compiler expected to emit a warning, i.e. keep the behavior all compilers have todayAttribute placementSince we don't use attributes heavily, I was not well-versed in what is a valid placement for an attribute. The free-floating one being invalid makes sense in retrospect, and could've been placed on the class name instead. My example was based on the typical syntax I'm used to in various game engines.As far as members go though, I did mean to annotate themIs this placement between the name and the trailing semicolon valid? For the purpose I have in mind, it would help readability, and most especially match the existing use of code generation tags in various engines while allowing automatic upgrades of the code with tools.class Test {
int m_member [[no_unique_address]];
};If it's not valid, would a proposal to make it valid make sense?Attributes vs ReflectionAs a reminder, the motivation is to move from made-up syntax parsed by custom tools to an attribute-based syntax, that is parsed by more standard tools like Clang, and facilitates the eventual migration to a C++ custom attribute and reflection-based syntax whenever those features come into the standard. Reflection is coming, but it seems like it will be a long time before it's powerful enough to support all-purpose code generation. So I see a lot of value in providing a migration path.Note also that reflection (which I see proposed as an alternative by others as I write this) will not remove the need to annotate the code with custom tags. It's the most convenient way to express that such and such member variable should be exposed for modification in the editor, or transmitted across the network, and how? So custom attributes are something that should eventually work hand-in-hand with reflection, one is not a substitute for the other.Cheers,GabrielLe lun. 12 févr. 2024, à 09 h 14, Arthur O'Dwyer <arthur.j.odwyer@gmail.com> a écrit :On Mon, Feb 12, 2024 at 7:04 AM Patrice Roy via SG14 <sg14@lists.isocpp.org> wrote:* P3132 Accept attributes with user-defined prefixes* P3134 Attribute [[asserts_rvo]]P3132 aims to make it easier to do tooling through user-defined attributes and has a number of additional upsides.P3134 aims to provide guarantees that a function's implementation can make it possible for appropriately written calls to that function to lead to the return value optimization[...] If you would be so kind as to (a) take a look at them, and ideally (b) provide suggestions / constructive criticism on this list or at the SG14 meeting this week, I would integrate this feedback into the official papers. In particular, I get the impression that the audience should be LEWG but I'd be open to knowing what the groups thinks.Both papers propose core-language features with no library impact, so they should be EWG (in fact, EWGI).Here's my feedback on P3132: I think it's mistaken and DOA.Seems to me that P3132's motivation is simply based on a misunderstanding of fact. Compilers are already required to accept (i.e. parse successfully) attributes with custom prefixes, according to the already-standardized attribute grammar.struct [[myPrefix::foobar]] Widget {};[[myPrefix::unused]] Widget w;is already a well-formed C++ program that must be accepted by every compiler, and indeed it is accepted (Godbolt).The reason the right side of the Tony Table at the top of page 4 isn't currently accepted is that it doesn't follow the grammar. You write:class PatrolPath {[[myCompany::RegisterClass]] Waypoints m_waypoints;[[myCompany::Property(INIT() RUNTIMEEDITABLE)]]};This is ungrammatical (Godbolt) because an attribute always has to be attached to something — it can't just be free-floating in the middle of the file.The compiler will treat the [[myCompany::RegisterClass]] attribute as applying to the declaration it's part of (i.e. `m_waypoints`).The compiler will reject [[myCompany::Property]] because it's not part of any declaration. All vendors except EDG will grudgingly accept it (contra the paper standard) if you add a trailing semicolon, so that the attribute appears to pertain to an "empty statement" in the middle of the class. (Classes aren't, technically, allowed to contain free-floating statements, either.)From the attributes' names, I'm sure the programmer meant them to apply to the class itself, not to the members. The way you'd do that in C++ is (Godbolt):class [[myCompany::RegisterClass]] [[myCompany::Property(INIT() RUNTIMEEDITABLE)]] PatrolPath {Waypoints m_waypoints;};Examples of attributes that work this way (on a class declaration/definition) include [[nodiscard]], [[clang::trivial_abi]], and my proposed [[trivially_relocatable]].The Tony Table at the bottom of page 4 already works correctly out of the box (Godbolt):[[gnu::flatten]] [[msvc::flatten]] void f();is accepted by all vendors. Of course a good compiler will give you a warning, because logically one of these two situations must apply:- The compiler doesn't recognize the attribute you typed, which means you might have made a typo. E.g. maybe you wrote [[gnu::flatten]] when you meant [[gnu::flat]].- The compiler does recognize the attribute you typed (or a prefix of it), but doesn't support it, which means you're asking for something the compiler knows it literally can't provide.Vendors rightly shy away from simply swallowing those errors; they want to helpfully surface them to the average user.If you're a power user who knows exactly what you're doing, then you can turn off that warning in any of several ways — the big two being:- Put -Wattributes in your build flags (this is the big "I know what I'm doing" hammer: not recommended)- Use a macro like `#define FLATTEN [[...]]` to eliminate the attribute on platforms that would otherwise warn about a lack of supportFinally, P3132 links to two StackOverflow questions specifically about libclang:- How to use custom C++ attributes with Clang libTooling without modifying Clang code? (Jan 2022)The gist of these questions/answers, IIUC, is that libclang will parse unknown attributes, but will not represent them in the AST; therefore, libclang users can't see any representation of what attributes were present at parse time. Basically, libclang treats unknown attributes like comments or preprocessor directives; they just disappear. This does seem suboptimal from the libclang-user's point of view! But I guess they do it that way because it's hard to know how to represent an unknown macro's "token soup" argument list, and/or to save memory (same reason they discard the text of comments).The reader (like me) will be sympathetic to those SO questioners. But that's 100% a bug report you should file against the LLVM project; it has nothing at all to do with the paper standard. In fact, someone's beaten you to it! See llvm/llvm-project #57748.I think P3132 would be better off not being in the February mailing at all. Of course you should feel free to (and probably go ahead and) submit it anyway — don't take my opinion as utter gospel — but you should at least be prepared for WG21 to reject it for basically the above reasons: "This is an ill-informed (duplicate) Clang bug report, not a WG21 proposal at all."my $.02,Arthur