[Cfp-interest] exploring __attribute__

David Hough CFP pcfp at oakapple.net
Fri Jul 25 16:19:33 PDT 2014


I followed up on Ian's suggestion and expanded the syntax discussion to
include __attribute__




Syntax for Directives in C

IEEE 754-2008 requests languages to define directives for specifying
mandatory and permissible compilation attributes.    An example of the
difference is a mandatory alternate exception handling 
directive to perform abrupt underflow handling, in contrast to
a permissible optimization directive that allows using fast hardware modes for
handling underflowed results and subnormal operands if they exist.

We've gotten some feedback that #pragma is not desirable syntax for mandatory
directives, and that try/catch semantics that we need does not match well enough
to C++ try/catch.     So that's an opportunity to step back and think about
what we really need.

The basic #pragma conceptual syntax is

{
#pragma STDC PROPERTY value

code
}

and the pragma affects all the code in the compound statement.
There are already three such pragmas in standard C.

  #pragma STDC FP_CONTRACT on-off-switch
  #pragma STDC FENV_ACCESS on-off-switch
  #pragma STDC CX_LIMITED_RANGE on-off-switch

Note that these pragmas 

 can occur either outside external declarations
 or preceding all explicit declarations and statements inside a
 compound statement

The catch/try syntax we considered was really just a syntactic
transformation of a corresponding #pragma approach:

try { 
code0
}
catch (FE_INVALID) {
code1
}

is conceptually equivalent to

{
#pragma STDC FENV_EXCEPT FE_INVALID goto L1 
code0
goto L2;
}
L1:
 code1
L2:

The try/catch form is a little less verbose, but has the drawback that
the exception list (FE_INVALID in this case) has to be known in order to
compile code0, even though the exception list appears syntactically after
the code that it modifies.

The try/catch paradigm happens to correspond rather closely to the 
control-transfer variety of alternate exception handling, but not closely to
the value-substitution variety of alternate exception handling,
nor to other kinds of compiler directives controlling optimizations.

So perhaps we should consider something more general.
Is there a more natural C-like syntax for specifying how a compound
statement should be compiled?

Another possible prototype comes from OpenMP 3.0:

  #pragma omp parallel [ clause[ [ , ]clause] ...] new-line
  structured-block

 where "structured-block" is defined as

  a single statement or a compound statement with a single entry
  at the top and a single exit at the bottom

It's interesting that OpenMP puts the controlling #pragma before the
compound statement, while FP_CONTRACT etc are within the compound statement.
I'm not aware of a compelling compiler-implementation
reason to do it one way or the other, but it
might make more sense to do it consistently.


Abstracting all this, we'd like to have a way of specifying attributes 
for compound statements.    Can we really do better than #pragma?
Some attributes are requirements, others just suggestions.


How about a general __attribute__ keyword that can attach to most any 
syntactic unit?
Ian suggests this approach and lists the positives:

 - It's reasonably understandable.
 - It avoids new keywords that conflict with user names.
 - It avoids the objections to pragmas.
 - It can apply to any compound statement including loops and if statement then or else clauses.
 - It handles substitution etc. not just trapping.
 - It can include non-floating-point exception handling.
 - It can include errno error handling.
 - It can include finally.
 - It (all, or the FP exception subset) could easily be added to C++.
 - Gcc / g++ users should like it.
 - It works with a one pass compiler.

The main negative is that it lists the exceptional case before the normal case,
which is backwards for persons reading code,
but it's a positive for one-pass compiler writers.

I'd interpret it thus:

__attribute__ (xyz) {
code
}

as equivalent to what we've been writing as

{
#pragma STDC xyz
code
}

where xyz might be very general:

fe_catch_after(flaglist); code1 	# test after execution
fe_catch_asap(exceptionlist); code1 	# catch asap
fe_catch(exceptionlist); code1		# asap or after, implementation choice
fe_sub(exceptionlist); code1		# code1 computes the substitute value
fe_abrupt();				# abrupt underflow
 
It looks like a function invocation followed by general code1, but the 
function names are really keywords; the general code1 would most likely be
pretty simple, typically a goto, for the fe_catch flavors.

Our existing pragmas and other optimization and expression evaluation
attributes could fit in as well:

  #pragma STDC FP_CONTRACT on-off-switch
  #pragma STDC FENV_ACCESS on-off-switch
  #pragma STDC CX_LIMITED_RANGE on-off-switch

become e.g.

__attribute__ (FP_CONTRACT(on)) {}
or
__attribute__ (FP_CONTRACT on) {}

multiple attributes could be handled something like

__attribute__ (attribute1) (attribute2) {

Note that the GCC feature that inspires this line of thought
has double parentheses around xyz:

__attribute__ ((xyz)) 

no doubt for good reasons that I don't know about.
And GCC __attribute__ doesn't apply to compound statements as I suggest;
that idea comes from OpenCL.


More information about the Cfp-interest mailing list