1*f0fbc68bSmrg# Coding standard 2*f0fbc68bSmrg 3*f0fbc68bSmrgI guess I should document this, it might not be obvious. 4*f0fbc68bSmrg 5*f0fbc68bSmrglibcody is implemented in C++11. Because it's used in compiler 6*f0fbc68bSmrgdevelopment, we can't use the latest and greatest. 7*f0fbc68bSmrg 8*f0fbc68bSmrgThe formatting is close to GNU, but with a few differences. 9*f0fbc68bSmrg 10*f0fbc68bSmrg## Extensions to C++11 11*f0fbc68bSmrg 12*f0fbc68bSmrgIt uses __VA_OPT__ when available, falling back on GNU's variadic 13*f0fbc68bSmrgmacro `,#` extension. This is in the `Assert` macro, so one can have 14*f0fbc68bSmrgmulti-argument template instantiations there. Not that libcody does 15*f0fbc68bSmrgthat, but this is code I used elsewhere. 16*f0fbc68bSmrg 17*f0fbc68bSmrg## GNU 18*f0fbc68bSmrg 19*f0fbc68bSmrgThe underlying formatting is GNU style. Here are a few notes about 20*f0fbc68bSmrgthings that commonly catches programmers unfamiliar with it is: 21*f0fbc68bSmrg 22*f0fbc68bSmrg* Spaces between binary operators. Particularly in a function call, 23*f0fbc68bSmrg between the name and the open paren: 24*f0fbc68bSmrg 25*f0fbc68bSmrg ```c++ 26*f0fbc68bSmrg Fn (a + b, ary[4], *ptr); 27*f0fbc68bSmrg ``` 28*f0fbc68bSmrg 29*f0fbc68bSmrg In general GNU style uses a lot more whitespace than Clang-style. 30*f0fbc68bSmrg We're not trying to cram as much code as possible onto a page! 31*f0fbc68bSmrg 32*f0fbc68bSmrg* Scope braces are always on a line of their own, indented by 2 33*f0fbc68bSmrg spaces, if they're a sub-statement of an `if`, `for` or whatever: 34*f0fbc68bSmrg 35*f0fbc68bSmrg ```c++ 36*f0fbc68bSmrg if (bob) 37*f0fbc68bSmrg { 38*f0fbc68bSmrg Frob (); 39*f0fbc68bSmrg Quux (); 40*f0fbc68bSmrg } 41*f0fbc68bSmrg ``` 42*f0fbc68bSmrg 43*f0fbc68bSmrg Conditions and loops containing a single statement should not use `{}`. 44*f0fbc68bSmrg FWIW this was my personal indentation scheme, before I even met GNU code! 45*f0fbc68bSmrg 46*f0fbc68bSmrg* The same is true for a function definition body, except the 47*f0fbc68bSmrg indentation is zero: 48*f0fbc68bSmrg 49*f0fbc68bSmrg ```c++ 50*f0fbc68bSmrg int Foo () 51*f0fbc68bSmrg noexcept // indented 52*f0fbc68bSmrg { 53*f0fbc68bSmrg return 0; 54*f0fbc68bSmrg } 55*f0fbc68bSmrg ``` 56*f0fbc68bSmrg 57*f0fbc68bSmrg* Initialization bracing is not like scope bracing. There tends to be 58*f0fbc68bSmrg more flexibility. 59*f0fbc68bSmrg 60*f0fbc68bSmrg* Break lines at 80 chars, this should be /before/ the operator, not after: 61*f0fbc68bSmrg 62*f0fbc68bSmrg ```c++ 63*f0fbc68bSmrg a = (b 64*f0fbc68bSmrg + c); 65*f0fbc68bSmrg ptr 66*f0fbc68bSmrg ->MemberFn (stuff); 67*f0fbc68bSmrg Func 68*f0fbc68bSmrg (arg); 69*f0fbc68bSmrg ``` 70*f0fbc68bSmrg 71*f0fbc68bSmrg Thus you can tell what lines are continued from the previous by 72*f0fbc68bSmrg looking at their start. Use parens to control indentation. 73*f0fbc68bSmrg 74*f0fbc68bSmrg If you find yourself wanting to break a line at `.`, don't. 75*f0fbc68bSmrg Refactor your code to avoid needing that. 76*f0fbc68bSmrg 77*f0fbc68bSmrg* Template instantiations and C++ casts should have no space before the `<`: 78*f0fbc68bSmrg 79*f0fbc68bSmrg ```c++ 80*f0fbc68bSmrg std::vector<int> k; 81*f0fbc68bSmrg static_cast<T> (arg); // space before the ( though 82*f0fbc68bSmrg ``` 83*f0fbc68bSmrg 84*f0fbc68bSmrg* Pointer and reference types need a space before the `*` or `&`, if 85*f0fbc68bSmrg the preceding token is ascii text (a cpp-identifier): 86*f0fbc68bSmrg 87*f0fbc68bSmrg ``` 88*f0fbc68bSmrg int *ptr; 89*f0fbc68bSmrg int **ptr_ptr; 90*f0fbc68bSmrg int *&pref = ptr; 91*f0fbc68bSmrg ``` 92*f0fbc68bSmrg 93*f0fbc68bSmrg See below a difference in qualifier placement. 94*f0fbc68bSmrg 95*f0fbc68bSmrg* Code should compile without warnings. 96*f0fbc68bSmrg 97*f0fbc68bSmrg## Not GNU 98*f0fbc68bSmrg 99*f0fbc68bSmrg### Names 100*f0fbc68bSmrg 101*f0fbc68bSmrgUnlike GNU code, variants of Camel Case are used. use `PascalCase` 102*f0fbc68bSmrgfor function, type and global variable names. Use `dromedaryCase` for 103*f0fbc68bSmrgmember variables. Block-scope vars can be `dromedaryCase` or 104*f0fbc68bSmrg`snake_case`, your choice. 105*f0fbc68bSmrg 106*f0fbc68bSmrg### Type qualifiers 107*f0fbc68bSmrg 108*f0fbc68bSmrgType qualifiers go after the thing they qualify. You have to do this 109*f0fbc68bSmrgfor pointers anyway, and read them inside-out, because, C Just being 110*f0fbc68bSmrgconsistent: 111*f0fbc68bSmrg 112*f0fbc68bSmrg```c++ 113*f0fbc68bSmrgint const foo = 5; // constant int 114*f0fbc68bSmrgint *const pfoo = nullptr; // constant pointer to int 115*f0fbc68bSmrg``` 116