GCC C++ Coding Conventions
This is a proposed set of coding conventions to be used when writing GCC in C++. The intention is to develop this on the wiki, and move them to http://gcc.gnu.org/codingconventions.html when they are stable.
For some additional background information, please see RFC:Switching implementation language to C++
General Guidelines
C++ code must conform to the C++98 standard, with the addition that the long long type may be used if the host C++ compiler supports it. (The treatment of long long remains the same as it is today.)
- Every version of GCC must be buildable by the previous version of GCC.
- We will periodically pick a stable version of GCC, and require that that version of GCC be able to build all versions of GCC up to and including the next stable version. E.g., we may decide that all newer versions of GCC should be buildable with GCC 4.3.5.
- It is desirable that it be possible to build GCC with C++ compilers other than GCC itself. If testing reveals that reasonably recent versions of non-GCC C++ compilers can not compile GCC, then GCC code should be adjusted accordingly.
Supporting libraries such as libiberty will continue to provide a C interface. C++ may only be used in the directories gcc, libcpp and fixincludes.
- All use of C++ features is subject to the decisions of the maintainers of the relevant components. (This restates something that is always true for gcc, which is that component maintainers make the final decisions about those components.)
When it is reasonably possible, use of prohibited features of C++ gives some warning during bootstrap. So we would have perhaps a new warning -Wgcc-cxx-style which detects most "easy" violations of our own coding rules.
Indentation rules are defined to be compatible with some use of some pretty-printer like astyle, and code should be when possible indented automatically.
C++ features
- C++ is a complex language. We do not want to use all aspects of it.
- The following features of the C++ language may not be used in GCC code.
RTTI and dynamic_cast (these features may be permitted when certain non-default --enable-checking options are enabled).
- Disabling RTTI will save space in the compiler. Checking the type of a class at runtime usually indicates a design problem. If you need classes to behave differently at runtime, use a virtual method. If you need to know the type of a class for some other reason, use an enum.
- Exceptions and throw specifications
- Current GCC code is not exception safe. Disabling exceptions will permit the compiler itself to be slightly more optimized.
In particular, GCC may be built with -fno-exceptions and -fno-rtti.
- These restrictions notwithstanding, newly written GCC code should be exception safe, to permit for future reconsideration of these standards.
- Mark Mitchell: That would mean some relatively major changes in style. For example, we'd have to get used to using auto_ptr, and, in general, using resource-acquisition-as-initialization everywhere. Of course, I think it's good practice, but it's a relatively high bar.
- The following features of the C++ language should in general be avoided in GCC code.
- Multiple inheritance.
- Multiple inheritance is confusing and rarely useful.
- Defining new templates (use of existing templates, e.g., from the standard library, is fine).
- This may be overly cautious and may be relaxed over time.
- Nested namespaces.
- Not expected to be useful in the GCC code base.
- Conversion operators.
- All conversions should be explicit to avoid confusion
using statements.
- In general a reference to a given name should mean the same thing in any GCC source file.
- Multiple inheritance.
- The following features of the C++ language are explicitly permitted in GCC code.
- Classes with public and private methods, data members, and constructors.
- You must define a default constructor if your class defines member variables and has no other constructors. Otherwise the compiler will do it for you, badly.
Single argument constructors should always be declared explicit (implementing a warning for this is likely useful in general).
PaoloBonzini: Try to avoid copy constructors and assignment operators. Anything that includes pointer members and a destructor should disable copy constructors and assignment operators by declaring TypeName(const TypeName&); void operator=(const TypeName&); as private (maybe we will want a macro for this).
- Destructors make a class non-POD, and as such should be used only when necessary.
- Namespaces; nested namespaces should be avoided.
- Use of the C++98 standard library, including the Standard Template Library.
- Classes with public and private methods, data members, and constructors.
- The following features of the C++ language may be used with care when appropriate in GCC code.
- Class inheritance.
- Public class inheritance may be used when appropriate for the data structure. Private and protected inheritance should normally be avoided.
- Virtual functions.
- Using virtual functions increases the size of an object of an instance of the class by one pointer. Therefore virtual functions must be avoided in objects which are widely allocated, such as an GIMPLE or RTL. However, virtual functions are acceptable where we use hooks today.
- Function and method overloading.
Function overloading can be confusing. However, in some cases introducing new function names adds little value, as in the current distinction between build_index_type and build_index_2_type. Function overloading is permitted provided the overloaded functions are semantically identical or at least very similar. Virtual functions should not be overloaded.
- Default arguments.
- Default arguments are another type of function/method overloading, and the same rules apply: it is permitted if the result is semantically identical. Default arguments must always be POD values and may not run constructors. Virtual functions should not have default arguments.
- Operator overloading.
- Operator overloading is only permitted in three cases.
operator<< may be implemented as appropriate to print a value to a stream.
- Operators may only be overloaded for types which implement numeric values, where the overloaded operators implement the usual numeric semantics.
operator() may be implemented as necessary for use with standard classes, such as for a std::sort comparator.
- Appropriate operators required for iterators and smart pointers. Try to avoid complex iterators (e.g. restrict to input iterators).
- Operator overloading is only permitted in three cases.
- Class inheritance.
At least for now we will continue to use printf style I/O rather than <iostream> style I/O. The latter should only be used in brand new areas, or after an agreed upon flag day transition. Since GCC already type checks printf arguments, <iostream> does not bring any clear benefits.
LaurynasBiveinis: I propose to ban <iostream> style I/O in brand new areas too, as it needlessly complicates i18n, unless something like Boost Format is used. (I do not propose introduce Boost dependency; this is just an indication how IMHO C++ I/O should look like).
BasileStarynkevitch: I believe that for all debugging or dumping outputs1, using <iostream> style I/O should become the norm, not the exception. In particular, because plugins (e.g. MELT) or other GCC extensions could be happy to output a dump into e.g. a memory stream, etc. And C++ <iostream> style is much cleaner for outputting in arbitrary streams, including memory, that <cstdio>
- Individual exceptions to the above rules may be made if the maintainers agree. The existence of such exceptions does not imply that the rules may be avoided in other cases.
C++ Coding Conventions
- The general guideline is to continue to follow the current C coding conventions where they make sense.
- All current GCC code uses a space between the function name and the left parenthesis in a function call. Essentially all C++ code omits that space. For the present we will retain the space. It is possible that in the future we will switch the code with a flag day.
- In new code variables which are used in a small scope should be defined at the point of first use, rather than at the top of the function. Variables which are used throughout the function may be defined at the top of the function, as in C.
- Classes.
- Indent all elements defined within the body of a class by two spaces.
- All constructors should initialize all data members.
- The names of methods and data members may be short as long as they are clear.
- All data members should be private.
- All data members should have names which end with an underscore.
- Where appropriate, a data member may have an accessor method which does nothing but return the value of the member. The name of such a method should be the same as the name of the member, without the trailing underscore.
When a method refers to a non-static data member, it should always qualify the reference with this->.
This makes it clear to the reader where the value is coming from. It also means that if the class is later converted to a template, there will be no difficulties with two-phase name lookup. It is understood that this convention is not used in all C++ code. Note that this is not a real change from the existing C code, where there is no implicit this->.
JackLloyd: Should there be a warning to check this? Something like -Wno-implicit-this
- When defining a class, first define all public types, then all public constructors, then all public methods.
- Method bodies may only appear in the class definition if they are very short, no more than five lines. Otherwise the method body should be defined outside of the class definition.
1 class my_class {
2 public:
3 my_class()
4 : field1_(0), field2_(NULL_TREE)
5 { }
6
7 // Meaningful comment.
8 int
9 field1()
10 {
11 return this->field1_;
12 }
13
14 private:
15 // Comment about field1.
16 int field1_;
17 // Comment about field2.
18 tree field2_;
19 };
- Note that the rules for classes do not apply to structs. Structs continue to behave as before, and in particular there is no need to add a trailing underscore to field names.
- When it is appropriate to use a child class with virtual functions, the virtual functions should all be declared as protected. Code should explicitly distinguish between the interface which the parent class presents to users of the class (the public methods) and the interface which the child class implements (the protected virtual methods). (The destructor is an exception here; a virtual destructor may and indeed normally should be public).
- Definitions within the body of a namespace are not indented.
- In general lines should be limited to 80 characters. In C++ code function names are often longer. If this would cause the first function parameter with its type to exceed 80 characters, it should appear on the next line indented four spaces.
1 void
2 very_long_class_name::very_long_function_name(
3 very_long_type_name arg)
4 {
More precisely, any output which does not need to be internationalized or localized for a French or Chinese GCC user; and dump output is in that case (and a Gimple textual output also would be in that case). (1)