Project: sysdig (Observability and Analysis / Observability)
File: coding_conventions.md

0 Introduction Sysdig strives for a consistent high quality code base and uses the conventions below. If you are going to commit code that doesn't follow them, then you put the work on us. :-(. If you use vim or emacs, you can put a custom configuration file in the base directory of sysdig in order to follow the conventions. Also, note that the conventions in this file apply strictly to the userspace part of sysdig. For the kernel code, you should refer to https://www.kernel.org/doc/html/latest/process/coding-style.html and always run checkpatch.pl from the kernel tree before submitting pull requests. Thanks for your attention and time. 1 Curly Braces Every curly brace ("{" and "}") should go on its own line. Example: if(a == 0) { b = 1; } 2 If and for statements Every `if` and `for` statement should have the curly braces. Example: if(a == 0) { b = 1; } and not if(a == 0) b = 1; 3 Whitespace usage Spaces are used in the following way: int32t foo(int32t a, int32_t b) { for(j = 0; j < 10; j++) { foo(a, b); } } Note that: in a function declaration, there is no space between the function name and the "(". in a function declaration, there is no space between the "(" and the first parameter. in a statement (e.g `for`, `while`...), there is no space between the "for" and the "(". in a statement (e.g `for`), there is no space between the "(" and the variable name. in a function call, there is no space between the function name and the "(". in a function call, there is no space between the "(" and the first parameter. "," and ";" work like in English: there should be a space after them. 4 Primitive types For portability reasons, please use the standard C99 types instead of the native C types like `int` and `long`. C99 types types will be available in all the user level sysdig source files: Example: int32_t foo; 5 Commenting Style Comments should be in the C++ style so we can use `/ /` to quickly remove portions of code during development. Example: // this is a comment 6 Commenting Content Code comments work in the following 2-level way: A three-line comment should document what the code does and give higher level explanations. A one line comment should detail single code lines or explain specific actions. Example: // // Swap two variables // int a = 1, b = 2, t; // make a copy of a t = a; // perform the swap a = b; b = t; 7 Class variables In order to know whether a variable belongs to a `class` or a `function` we start member variables with

Example: public int32t mcounter; 8 Global variables Similarly, in order to know whether the variable is global or not, we start globals with "`g_`". Example: int g_nplugins; 9 Capitalization The naming convention is camel-cased "Unix" style, i.e. always lower case. Words are separated by underscores. Example: int32t gglobalbeancounter; int32t countbeans(); and not, int32_t GlobalBeanCounter; 10 Packed Structures Packed structures should use the GCC and MSVC-style supported `pragma`: struct frame_control { struct fields.... }; 11 OS-specific macros There's an online wiki which enumerates the different macros for compilers, operating systems, and architectures. It's available at . Generally speaking we use the operating system page: . 12 64-bit constants Put an "LL" at the end of your 64 bit constants. Without the LL, on some platforms the compiler tries to interpret the constant on the right hand side as a long integer instead of a long long and in some platform this generate an error at building time. Example: x=0X00FF00000000000LL 13 Class Declaration Class declarations follow the following sequence constructors and destructor public functions public data private functions private data friend declarations Example: class foo { public: foo(); ~foo(); int32_t lonli(); int32t mval; private: int32_t temustra(); int32t mval2; }; 14 Struct guidelines We think hiding the presence of a pointer makes the code unnecessarily ambiguous and more difficult. Seeing a * in a variable declaration immediately identifies a pointer, which is easier to mentally keep track of! Also we think that defining the struct as a typedef makes forward declarations clunky and find using the C++ style when declaring our structs makes our lives easier. // // Us human parsers find this confusing. // typedef struct mystruct { uint16 mfield; } my_struct, *pmystruct; // // This is easier! // struct my_struct { uint16 mfield; }; 15 Temporary variables Since "j" is used less frequently in english prose than "a" or "i", we find that these variables (in hierarchical order) are great for counters: j, k, l, m, n. Example: int32_t j,k; for(j = 0; j < 10; j++) { for(k = 0; k < 10; k++) { int32_t foo = j + k; } } as opposed to: int32_t i,counter; for(i = 0; i < 10; i++) { for(counter = 0; counter < 10; counter++) { int32_t foo = i + counter; } } 16 Error management Error management inside libscap is done through return values, since the scap library is written in C. Error management in the rest of the sysdig user level code base is done through exceptions. We know there's a lot of debate between return values and exceptions. We decided to pick the latter, so please stick with that. Phew! That's it. Thanks! If we've left anything in the open, feel free to contact us and we'll be happy to get back to you. Also, you can look at the existing code and see how it's done. Have a good one!