This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Prefix attributes vs. grammar


"Prefix attributes" are a good example of what happens when you implement
a language feature without really designing it first.

What is the grammar supposed to be that allows these things?

The unvarnished grammar from the standard is, roughly:

  declaration:
    decl-specifier-seq declarator

One sane choice would be:

  declaration:
    decl-specifier-seq attributes [opt] declarator

That allows things like:

  void __attribute__((x)) f();

It seems, however, that current practice allows:

  const __attribute__((x)) int *f();

Despite the fact that this is utterly grotesque.  Here the
attributes apparently apply to `f' and not `const' or `int',
but it is hard to be sure.

That would seem to imply that attributes *are* decl-specifiers.

Well, then, they must actually be type-specifiers, because things
like `if (int x = 3)' use type-specifier-seq, rather than
decl-specifier-seq, since things like `extern' are not allowed
here.  Well, or eveywhere that we have type-specifier in the grammar,
we really mean type-specifier-or-attribute.  This is getting bizarre, to
say the least.

Then, I see that we have tests for constructs like:

  typedef void (__attribute__((__stdcall__))* pfn)();

This probably means that the pointed to function uses the `stdcall'
calling convention.  It's a safe bet that nobody has any idea what
this means in the presence of overload resolution, template
instantiation, etc.

Anyhow, aside from the semantics, the syntax here is getting even
weirder.  That `(...*pfn)' bit is a direct-declarator.  The
bit inide the parentheses is just a declarator.  Were it not for
the attribute stuff, it would be:

  declarator:
    ptr-operator declarator

I guess we now have:

   declarator:
     attributes [opt] ptr-operator declarator

?  Can the attributes come after the ptr-operator?

We have implemented a semantically dubious construct with an atrocious
syntax.

So, I went and read the (well-written, but still somewhat incomplete) 
section on attributes in the manual that describes attribute syntax, but I 
am horrified.  The chances of implementing that correctly, not just in the
parser but throughout the compiler, are nil.

I am thinking that the new C++ parser is going to allow attributes only 
directly after a decl-specifier-seq; in other words, you can do:

  int __attribute__((__stdcall__)) f (double __attribute__ ((unused)) x);

but not the other stuff shown above.  In other words, prefix attributes
are just like postfix attributes, only they come before the declarator
instead of afterwards.

Note that this is still fully general in that you can always write:

  typedef void (*pfn) ();
  typedef pfn __attribute__ ((__stdcall__)) stdcall_pfn;

So, we can still have whatever alleged semantics we had before.

This would also make the question of what attributes bind where a lot
simpler.

Does anyone object to narrowing the syntax in this way?

-- 
Mark Mitchell                mark@codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]