gcc/libcody/CODING.md
Nathan Sidwell 362303298a Add libcody
In order to separate compiler from build system, C++ Modules, as
implemented in GCC introduces a communication channel between those
two entities.  This is implemented by libcody.  It is anticipated that
other implementations will also implement this protocol, or use
libcody to provide it.

	* Makefile.def: Add libcody.
	* configure.ac: Add libcody.
	* Makefile.in: Regenerated.
	* configure: Regenerated.
	gcc/
	* Makefile.in (CODYINC, CODYLIB, CODYLIB_H): New. Use them.
	libcody/
	* configure.ac: New.
	* CMakeLists.txt: New.
	* CODING.md: New.
	* CONTRIB.md: New.
	* LICENSE: New.
	* LICENSE.gcc: New.
	* Makefile.in: New.
	* Makesub.in: New.
	* README.md: New.
	* buffer.cc: New.
	* build-aux/config.guess: New.
	* build-aux/config.sub: New.
	* build-aux/install-sh: New.
	* client.cc: New.
	* cmake/libcody-config-ix.cmake
	* cody.hh: New.
	* config.h.in: New.
	* config.m4: New.
	* configure: New.
	* configure.ac: New.
	* dox.cfg.in: New.
	* fatal.cc: New.
	* gdbinit.in: New.
	* internal.hh: New.
	* netclient.cc: New.
	* netserver.cc: New.
	* packet.cc: New.
	* resolver.cc: New.
	* server.cc: New.
	* tests/01-serialize/connect.cc: New.
	* tests/01-serialize/decoder.cc: New.
	* tests/01-serialize/encoder.cc: New.
	* tests/02-comms/client-1.cc: New.
	* tests/02-comms/pivot-1.cc: New.
	* tests/02-comms/server-1.cc: New.
	* tests/Makesub.in: New.
	* tests/jouster: New.
2020-12-15 07:09:59 -08:00

2.9 KiB

Coding standard

I guess I should document this, it might not be obvious.

libcody is implemented in C++11. Because it's used in compiler development, we can't use the latest and greatest.

The formatting is close to GNU, but with a few differences.

Extensions to C++11

It uses VA_OPT when available, falling back on GNU's variadic macro ,# extension. This is in the Assert macro, so one can have multi-argument template instantiations there. Not that libcody does that, but this is code I used elsewhere.

GNU

The underlying formatting is GNU style. Here are a few notes about things that commonly catches programmers unfamiliar with it is:

  • Spaces between binary operators. Particularly in a function call, between the name and the open paren:

    Fn (a + b, ary[4], *ptr);
    

    In general GNU style uses a lot more whitespace than Clang-style. We're not trying to cram as much code as possible onto a page!

  • Scope braces are always on a line of their own, indented by 2 spaces, if they're a sub-statement of an if, for or whatever:

    if (bob)
      {
        Frob ();
        Quux ();
      }
    

    Conditions and loops containing a single statement should not use {}. FWIW this was my personal indentation scheme, before I even met GNU code!

  • The same is true for a function definition body, except the indentation is zero:

    int Foo ()
      noexcept // indented
    {
      return 0;
    }
    
  • Initialization bracing is not like scope bracing. There tends to be more flexibility.

  • Break lines at 80 chars, this should be /before/ the operator, not after:

    a = (b
         + c);
    ptr
    ->MemberFn (stuff);
    Func
    (arg);
    

    Thus you can tell what lines are continued from the previous by looking at their start. Use parens to control indentation.

    If you find yourself wanting to break a line at ., don't. Refactor your code to avoid needing that.

  • Template instantiations and C++ casts should have no space before the <:

    std::vector<int> k;
    static_cast<T> (arg); // space before the ( though
    
  • Pointer and reference types need a space before the * or &, if the preceding token is ascii text (a cpp-identifier):

    int *ptr;
    int **ptr_ptr;
    int *&pref = ptr;
    

    See below a difference in qualifier placement.

  • Code should compile without warnings.

Not GNU

Names

Unlike GNU code, variants of Camel Case are used. use PascalCase for function, type and global variable names. Use dromedaryCase for member variables. Block-scope vars can be dromedaryCase or snake_case, your choice.

Type qualifiers

Type qualifiers go after the thing they qualify. You have to do this for pointers anyway, and read them inside-out, because, C Just being consistent:

int const foo = 5; // constant int
int *const pfoo = nullptr;  // constant pointer to int