Skip to content

Generalised attributes

November 8, 2012

GCC has recently implemented generalised attributes. In this post I will discuss what they are and how they can be useful.

Generalised attributes are an extendible means to specify compiler specific attributes for particular language constructs. Previously these have had compiler specific syntax, and as such, wouldn’t even compile with the wrong compiler. The GNU compiler uses __attribute__, and the Microsoft compiler uses the __declspec keyword.

Attributes are declared by placing an attribute specifier in a declaration. An attribute specifier is said to appertain to a particular entity in the declaration. In other words, the specifier applies to some part of the declaration. The specifier is either an alignas specification, or a list of attributes inside double square brackets ([[]]).

Note that the standard now prohibits the appearance of two left square brackets next to each other, even if it is an otherwise valid construct. The following is an example from 7.6.1 paragraph 6 of the standard of what is not allowed:

int p[10];
void f() {
  int x = 42, y[5];
  int(p[[x] { return x; }()]);
  y[[] { return 2; }()] = 2;
}

An attribute can usually appear in several places in a declaration, and it applies to a specific entity in the declaration depending on where it is placed. It usually applies to the entity to the left, although if it appears at the front of a declaration then it applies to the entities declared by that declaration.

For example, suppose that we had the following code:

[[attr1]] class [[attr2]] A
{
} a;

A b;

then attr1 will be applied to variable a, and attr2 will be applied to the whole class A. Therefore, the variable b, as an object of A, will have any attributes applicable to A, as defined by attr2.

Attributes can have arguments or not, attributes can be in a namespace, and the tokens appearing inside the [[]] can be anything other than [, ], (, ), {, }. Here are some examples from the GCC test suite.

[[gnu::unused]]
int
five(void)
[[gnu::noreturn]] // { dg-warning "ignored" }
{}

// You can make NON-template typedefs with a large alignment.
typedef double AlignedDoubleType [[gnu::aligned(16)]];

typedef int (*F [[gnu::warn_unused_result]]) (int);

typedef int (*F2 [[gnu::warn_unused_result]]) (int);

[[gnu::packed]] struct A // { dg-warning "attribute" }
{
  char c;
  int x;
  void f();
};

The noreturn attribute

One of the attributes defined in the standard is the noreturn attribute. Specifying that a function has the attribute noreturn means that it will not return. If such a function does return, then the behaviour is undefined. An example of a function that could have the noreturn attribute is exit.

About these ads

From → Language

2 Comments
  1. stronzo permalink

    So they disambiguated >> in a template expression but created a similar problem with [[? Brilliant!

    • It seems like it, although if you look at the discussion when they were designing generalised attributes (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf), it seems like there is a good reason that helps parsers.

      At any rate, I don’t see that anyone would need to type [[ that much anyway. As far as I can see it only happens when you use a lambda function inside an array access, and how often is that going to happen?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: