Chapter 6. Extensions to the C Language Family 159Currently, the dllexportattribute is ignored for inlined functions, but export can be forced byusing the -fkeep-inline-functions flag. The attribute is also ignored for undefined sym-bols.When applied to C++ classes. the attribute marks defined non-inlined member functions andstatic data members as exports. Static consts initialized in-class are not marked unless they arealso defined out-of-class.On cygwin, mingw and arm-pe targets, __declspec(dllexport) is recognized as a synonymfor __attribute__ ((dllexport)) for compatibility with other Microsoft Windows com-pilers.Alternative methods for including the symbol in the dll’s export table are to use a .def file withan EXPORTS section or, with GNU ld, using the -export-all linker flag.You can specify multiple attributes in a declaration by separating them by commas within the doubleparentheses or by immediately following an attribute declaration with another attribute declaration.Some people object to the __attribute__ feature, suggesting that ISO C’s #pragma should be usedinstead. At the time __attribute__ was designed, there were two reasons for not doing this.1. It is impossible to generate #pragma commands from a macro.2. There is no telling what the same #pragma might mean in another compiler.These two reasons applied to almost any application that might have been proposed for #pragma. Itwas basically a mistake to use #pragma for anything.The ISO C99 standard includes _Pragma, which now allows pragmas to be generated from macros.In addition, a #pragma GCC namespace is now in use for GCC-specific pragmas. However, it hasbeen found convenient to use __attribute__ to achieve a natural attachment of attributes to theircorresponding declarations, whereas #pragma GCC is of use for constructs that do not naturally formpart of the grammar.6.26. Attribute SyntaxThis section describes the syntax with which __attribute__ may be used, and the constructs towhich attribute specifiers bind, for the C language. Some details may vary for C++ and Objective-C.Because of infelicities in the grammar for attributes, some forms described here may not be success-fully parsed in all cases.There are some problems with the semantics of attributes in C++. For example, there are no man-glings for attributes, although they may affect code generation, so problems may arise when attributedtypes are used in conjunction with templates or overloading. Similarly, typeid does not distinguishbetween types with different attributes. Support for attributes in C++ may be restricted in future toattributes on declarations only, but not on nested declarators.Section 6.25 Declaring Attributes of Functions, for details of the semantics of attributes applying tofunctions. Section 6.32 Specifying Attributes of Variables, for details of the semantics of attributesapplying to variables. Section 6.33 Specifying Attributes of Types, for details of the semantics ofattributes applying to structure, union and enumerated types.An attribute specifier is of the form __attribute__ ((attribute-list)). An attribute list is apossibly empty comma-separated sequence of attributes, where each attribute is one of the following:• Empty. Empty attributes are ignored.• A word (which may be an identifier such as unused, or a reserved word such as const).• A word, followed by, in parentheses, parameters for the attribute. These parameters take one of thefollowing forms: