- Overview
-
Table of Contents
- Special Member Functions: Constructors, Destructors, and the Assignment Operator
- Operator Overloading
- Memory Management
- Templates
- Namespaces
- Time and Date Library
- Streams
- Object-Oriented Programming and Design Principles
- The Standard Template Library (STL) and Generic Programming
- Exception Handling
- Runtime Type Information (RTTI)
- Signal Processing
- Creating Persistent Objects
- Bit Fields
- New Cast Operators
- Environment Variables
- Variadic Functions
- Pointers to Functions
- Function Objects
- Pointers to Members
- Lock Files
- Design Patterns
- Dynamic Linking
- Tips and Techniques
- Five Things You Need to Know About C++11 Unions
- A Tour of C99
- A Tour of C1X
-
C++0X: The New Face of Standard C++
- Reference Wrapper
- The Performance Technical Report
- auto for the People
- Ironing Templates' Syntactic Wrinkles
- Visual C++ Becomes ISO Compliant
- A Garbage Collector for C++
- C99 Core Features in C++0X
- The <code>shared_ptr</code> Class
- The shared_ptr Class, II
- Lambda Expressions and Closures, Part I
- Lambda Expressions and Closures, Part II
- Lambda Expressions and Closures, Part III
- The Type Traits Library, Part I
- The Type Traits Library, Part II
- The Type Traits Library, Part III
- finally Revisited
- The Any Library
- The nullptr Keyword Proposal
- Delegating Constructors
- The Explicit Conversion Operators Proposal
- Conditionally-Supported Behavior
- The weak ptr Class Template, Part I
- The weak ptr Class Template, Part II
- POD Types Revisited
- The rvalue Reference Proposal, Part I
- The rvalue Reference Proposal, Part II
- Proposal for New String Algorithms
- Concepts, Part I
- Concepts, Part II
- constexpr: Generalized Constant Expressions
- The <u>constexpr</u> Proposal: Constructors
- Strongly-Typed enum Types
- C++09: The Road Ahead
- C++09: Proposals by Statuses
- Changing Undefined Behavior to Diagnosable Errors
- New Character Types
- The __func__ Predeclared Identifier is Coming to C++
- Static Assertions
- The extern template Proposal
- Variadic Templates, Part I
- Variadic Templates, Part II
- Variadic Templates, Part III -- Critique
- Using unique_ptr, Part I
- Using unique_ptr, Part II
- Unrestricted Unions, Part I
- Unrestricted Unions, Part II
- Unrestricted Unions, Part III
- Types With No Linkage as Template Arguments
- New Initialization Syntax
- Initializer Lists and Sequence Constructors
- New Standard Library Algorithms
- Class Member Initializers
- Inheriting Constructors
- Introducing Attributes
- The Removal of Concepts From C++0x
- The Future of C++0x, Part I
- The Future of C++0X, Part II
- The Debate About Attributes, Part I
- The Debate About Attributes, Part II
- The Debate About Attributes, Part III
- The Debate About Attributes, Part IV
- Forward Declarations of Enum Types
- The SCARY Iterators Proposal, Part I
- The SCARY Iterators Proposal, Part II
- Heading for Deprecation: <tt>export</tt>, Exception Specification and <tt>register</tt>
- The Rejection of the Unified Function Syntax Proposal
- Rvalue References as Object Members
- FCD Approved
- The Debate on noexcept, Part I
- The Debate on noexcept, Part II
- The Debate on noexcept, Part III
- About-face -- [[Attributes]] to Be Replaced with Keywords
- Will Delegating Constructors Be Removed From C++0x?
- Rvalue References: Past, Present and Future, Part I
- Rvalue References: Past, Present and Future, Part II
- Rvalue References: Past, Present and Future, Part III
- A Move in the Right Direction, Part I
- A Move in the Right Direction, Part II
- New Keywords for Inheritance Control, Part I
- New Keywords for Inheritance Control, Part II
- FDIS Approved
- C++0x Concurrency
- The Reflecting Circle
- We Have Mail
- The Soapbox
- Numeric Types and Arithmetic
- Careers
- Locales and Internationalization
The Debate About Attributes, Part I
Last updated Jan 1, 2003.
Attributes were voted into the Working Draft (WD) at the San Francisco meeting in October 2008. That voting wasn't unanimous (29 votes in favor of attributes, 7 against). Certain committee members expressed their concern about various aspects of the attributes proposal and some even said that their implementation wouldn't support the standard attributes at all (for further details, read the minutes from that meeting). The controversy about attributes has intensified recently because the original attributes proposal was extended last month at the Berlin meeting. It appears that my predictions about the aftershocks caused by the removal of concepts are materializing: although attributes are in the Working Draft, committee members who object to them want to see attributes removed from the Working Draft, while at the same time, other members strongly support attributes. In the first part of this series I will present the claims of those who object to attributes. The claims in favor of attributes will be presented in the second part.
Are Attributes Ignorable?
I introduced attributed recently. In the meantime, the committee has added three more attribute tokens to the standard: [[override]], [[base_check]] and [[hiding]]. I will not explain the meaning of the new attribute tokens here (they deserve a column of their own) but I believe that their semantic content is self-explanatory. They're all used in the context of a class hierarchy.
The main argument against the new attribute tokens is that compilers cannot ignore them. In other words, the new tokens (and some of the original attribute tokens) are in fact keywords in disguise. That's a significant change from the original proposal which was voted into the Working Draft. Initially, attributed were described as "just simple annotations that can always be ignored, with no semantic effect". Allow me to elaborate on this claim. Suppose you have a function such as std::exit() that never returns to its caller. According to the original attributes proposal, implementers can annotate such a function with the [[noreturn]] attribute in order to let the compiler optimize the code or suppress spurious warnings. The crucial point is that omitting the [[noreturn]] attribute shouldn't change the semantics of the program -- it will behave in exactly the same way whether exit() is annotated with [[noreturn]] or not. In fact, this criterion was the litmus test for determining whether a certain property should be expressed as an attribute or not. Now examine the [[final]] attribute. It violates the "ignorability" criterion. The compiler can't ignore [[final]]. If the program tries to override a member function that was annotated as such, that program is ill-formed. Put differently, [[fina]] (as well as [[align]], [[override]], [[base_check]] and [[hiding]]) carry semantic content that affects the behavior of the program; they cannot be ignored and they are not optional. Thus, although the original proposal explicitly said: "we were asked to offer guidance in order to prevent wholesale dumping of extension keywords into[...] attribute[s]...", we do effectively have attributes that are equivalent to context-sensitive keywords. You can still use final as an identifier in your code, but the [[final]] attribute works very much like a keyword. In this respect, committee members who have objected to attributes right from the start claim that this is a case of "creeping featurism", as semantics change was explicitly not part of the original intent for attributes. There are of course additional reasons for the objecting to standardized attributes:
The Case Against Attributes
Some of the claims against attributes come from mainstream programmers who were first exposed to the notion of attributes recently. Other claims come from committee members.
Ugly syntax. When I presented the notion of attributes in an article I noticed that the comments left by readers repeatedly expressed concerns about the funky [[attrib]] syntax. Of course, we have other syntactic monstrosities in C++ but there's no reason to add a new monstrosity unless it's completely unavoidable. The question is therefore: are attributes really indispensable?
Standardizing the nonstandard. The attempt to standardize attributes is problematic because vendors have been using attributes (in completely different ways) as a mechanism for specifying nonstandard properties of a certain construct. Each vendor uses a different syntactic form. Seemingly, such a chaotic state of affairs cries for standardization but there's a difference between standardizing only the syntactic form of attributes and standardizing the semantic content (which is usually implementation-dependent). In other words, the best thing the standards committee should do is leave the current state of affairs as-is instead of forcing yet another design-by-committee.
Syntactic confusion. Many vendors already support two(!) separate syntactic forms of attributes. Microsoft's Visual Studio for instance supports both [attribute] and __declspec(attribute) (their attributes are completely different from the WD's attributes) Adding a third form of attributes will confuse users and obfuscate C++ code.
Keywords in Disguise. As stated previously, attributes that aren't ignorable aren't really attributes in the narrow sense. Why not simply add new keywords to C++? This very argument was expressed by many C++ programmers who were exposed to the Working Draft's attributes but it's also expressed by committee members.
Are Attributes Keywords in Disguise?
The latter claim is perhaps the most interesting. Where do you draw the line between an attribute and a full-blown keyword? Clearly, ignorability is no longer a valid criterion for such a distinction because most of the attributes in the Working Draft aren't ignorable. Furthermore, tokens such as [[final]], [[override]] and [[hiding]] exist as true keywords in other programming languages so why sneak them into C++ as attributes? After all, they affect the most fundamental feature of C++ (a class), and other programming languages define them as first class keywords.
In the second part of this series I will present the arguments of attributes supporters and try to predict what will happen to attributes.
