GNU C++ Conformance to ANSI C++
*******************************

These changes in the GNU C++ compiler were made to comply more closely with the ANSI base document, The Annotated C++ Reference Manual (the ARM).  Further reducing the divergences from ANSI C++ is a continued goal of the GNU C++ Renovation Project.

Section 3.4, Start and Termination.  It is now invalid to take the address of the function main().

Section 4.8, Pointers to Members.  The compiler produces an error for trying to convert between a pointer to a member and the type void *.

Section 5.2.5, Increment and Decrement.  It is an error to use the increment and decrement operators on an enumerated type.

Section 5.3.2, Sizeof.  Doing sizeof on a function is now an error.

Section 5.3.4, Delete.  The syntax of a cast-expression is now more strictly controlled.

Section 7.1.1, Storage Class Specifiers.  Using the static and extern specifiers can now only be applied to names of objects, functions, and anonymous unions.

Section 7.1.1, Storage Class Specifiers.  The compiler no longer complains about taking the address of a variable which has been declared to have register storage.

Section 7.1.2, Function Specifiers.  The compiler produces an error when the inline or virtual specifiers are used on anything other than a function.

Section 8.3, Function Definitions.  It is now an error to shadow a parameter name with a local variable; in the past, the compiler only gave a warning in such a situation.

Section 8.4.1, Aggregates.  The rules concerning declaration of an aggregate are now all checked in the GNU C++ compiler; they include having no private or protected members and no base classes.

Section 8.4.3, References.  Declaring an array of references is now forbidden.  Initializing a reference with an initializer list is also considered an error.

Section 9.5, Unions.  Global anonymous unions must be declared static.

Section 11.4, Friends.  Declaring a member to be a friend of a type that has not yet been defined is an error.

Section 12.1, Constructors.  The compiler generates a default copy constructor for a class if no constructor has been declared.

Section 12.6.2, Special Member Functions.  When using a mem-initializer list, the compiler will now initialize class members in declaration order, not in the order in which you specify them. Also, the compiler enforces the rule that non-static const and reference members must be initialized with a mem-initializer list when their class does not have a constructor.

Section 12.8, Copying Class Objects.  The compiler generates default copy constructors correctly, and supplies default assignment operators compatible with user-defined ones.

Section 13.4, Overloaded Operators.  An overloaded operator may no longer have default arguments.

Section 13.4.4, Function Call.  An overloaded operator () must be a non-static member function.

Section 13.4.5, Subscripting.  An overloaded operator [] must be a non-static member function.

Section 13.4.6, Class Member Access.  An overloaded operator -> must be a non-static member function.

Section 13.4.7, Increment and Decrement.  The compiler will now make sure a postfix operator ++ or operator -- has an int as its second argument.

Name Encoding in GNU C++
************************

In order to support its strong typing rules and the ability to provide function overloading, the C++ programming language encodes information about functions and objects, so that conflicts across object files can be detected during linking.  (This encoding is also sometimes called, whimsically enough, mangling; the corresponding decoding is sometimes called demangling.) These rules tend to be unique to each individual implementation of C++.

The scheme detailed in the commentary for 7.2.1 of The Annotated Reference Manual offers a description of a possible implementation which happens to closely resemble the cfront compiler.  The design used in GNU C++ differs from this model in a number of ways:

  * In addition to the basic types void, char, short, int, long, float, double, and long double, GNU C++ supports two additional types: wchar_t, the wide character type, and long long (if the host supports it).  The encodings for these are w and x respectively.

  * According to the ARM, qualified names (e.g., foo::bar::baz) are encoded with a leading Q.  Followed by the number of qualifications (in this case, three) and the respective names, this might be encoded as Q33foo3bar3baz.  GNU C++ adds a leading underscore to the list, producing _Q33foo3bar3baz.

  * The operator *= is encoded as __aml, not __amu, to match the normal * operator, which is encoded as __ml.

  * In addition to the normal operators, GNU C++ also offers the minimum and maximum operators >? and <?, encoded as __mx and __mn, and the conditional operator ?:, encoded as __cn.

  * Constructors are encoded as simply __NAME, where NAME is the encoded name (e.g., 3foo for the foo class constructor).  Destructors are encoded as two leading underscores separated by either a period or a dollar sign, depending on the capabilities of the local host, followed by the encoded name.  For example, the destructor foo::~foo is encoded as _$_3foo.

  * Virtual tables are encoded with a prefix of _vt, rather than __vtbl.  The names of their classes are separated by dollar signs (or periods), and not encoded as normal: the virtual table for foo is __vt$foo, and the table for foo::bar is named __vt$foo$bar.

  * Static members are encoded as a leading underscore, followed by the encoded name of the class in which they appear, a separating dollar sign or period, and finally the unencoded name of the variable.  For example, if the class foo contains a static member bar, its encoding would be _3foo$bar.

  * GNU C++ is not as aggressive as other compilers when it comes to always generating Fv for functions with no arguments.  In particular, the compiler does not add the sequence to conversion operators.  The function foo::bar() is encoded as bar__3foo, not bar__3fooFv.

  * The argument list for methods is not prefixed by a leading F; it is considered implied.

  * GNU C++ approaches the task of saving space in encodings differently from that noted in the ARM.  It does use the TN and NXY codes to signify copying the Nth argument's type, and making the next X arguments be the type of the Yth argument, respectively.  However, the values for N and Y begin at zero with GNU C++, whereas the ARM describes them as starting at one.  For the function foo (bartype, bartype), GNU C++ uses foo__7bartypeT0, while compilers following the ARM example generate foo__7bartypeT1.

  * GNU C++ does not bother using the space-saving methods for types whose encoding is a single character (like an integer, encoded as i). This is useful in the most common cases (two ints would result in using three letters, instead of just ii).