logo

blog

My little blog can’t be this cute! git clone https://hacktivis.me/git/blog.git
commit: 59a6ca6b0a6a5ca53e13225b99826dd789aebcf4
parent 12fc01c2fe4bf2619f680a87378419dc37ad8407
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Mon, 11 Feb 2019 02:46:15 +0100

coding style: Write from scratch rather than copypasta

Diffstat:

Mcoding style.shtml171+++++++------------------------------------------------------------------------
1 file changed, 14 insertions(+), 157 deletions(-)

diff --git a/coding style.shtml b/coding style.shtml @@ -8,8 +8,8 @@ <!--#include file="/templates/en/nav.shtml" --> <main> <h1>Coding Style</h1> - <p>This is taken from &copy; 2006-2015 <a href="//suckless.org">suckless.org</a> community, with few modifications because no coder have the same style.</p> - <p>Note that the following are guidelines and the most important aspect of style is consistency. Strive to keep your style consistent with the project on which you are working.</p> + <p>Done from scratch to note choices done so far instead of copying and modifying after it. This just denotes my preferred coding style but the most important is for a project’s code to be consistent.</p> + <p>And this applies to all programming languages that I use, even if I’ll use C vocabulary when applicable.</li> <h2>Recommended Reading</h2> <p>The following contain good information, some of which is repeated below, some of which is contradicted below.</p> <ul> @@ -17,163 +17,20 @@ <li><a href="https://www.kernel.org/doc/Documentation/CodingStyle">https://www.kernel.org/doc/Documentation/CodingStyle</a></li> <li><a href="http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man9/style.9?query=style&amp;sec=9">http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man9/style.9?query=style&amp;sec=9</a></li> </ul> - - - <h2>File Layout</h2> + <h2>Choices</h2> <ul> - <li>Comment with LICENSE and possibly short explanation of file/tool</li> - <li>Headers</li> - <li>Macros</li> - <li>Types</li> - <li>Function declarations<ul> - <li>Include variable names</li> - <li>For short files these can be left out</li> - <li>Group/order in logical manner</li> - </ul></li> - <li>Global variables</li> - <li>Function definitions in same order as declarations</li> - <li><code>main</code></li> - </ul> - <h2>C Features</h2> - <ul> - <li>Use C99 without extensions (ISO/IEC 9899:1999)<ul> - <li>When using gcc compile with -std=c99 -pedantic</li> - </ul></li> - <li>Use POSIX.1-2008<ul> - <li>When using gcc define <code>_POSIX_C_SOURCE 200809L</code></li> - <li>Alternatively define <code>_XOPEN_SOURCE 700</code></li> - </ul></li> - <li>Do not mix declarations and code</li> - <li>Do not use for loop initial declarations</li> - <li>Use <code>/* */</code> for comments, not <code>//</code></li> - <li>Variadic macros are acceptable, but remember<ul> - <li><code>__VA_ARGS__</code> not a named parameter</li> - <li>Arg list cannot be empty</li> - </ul></li> - </ul> - <h2>Blocks</h2> - <ul> - <li>All variable declarations at top of block</li> - <li><code>{</code> on same line preceded by single space</li> - <li><code>}</code> on own line unless continuing statement (<code>if else</code>, <code>do while</code>, &hellip;)</li> - <li>Use block for single statements iff<ul> - <li><p>Inner statement needs a block</p> -<pre><code>for (;;) { - if (foo) { - bar; - baz; - } -} -</code></pre></li> - <li><p>Another branch of same statement needs a block</p> -<pre><code>if (foo) { - bar; -} else { - baz; - qux; -} -</code></pre></li> - </ul></li> - </ul> - <h2>Leading Whitespace</h2> - <ul> - <li>Use tabs for indentation</li> - <li>Use spaces for alignment<ul> - <li>This means no tabs except beginning of line</li> - <li>Everything will line up independent of tab size</li> - <li>Use spaces not tabs for multiline macros as the indentation level is 0, where the <code>#define</code> began</li> - </ul></li> - </ul> - <h2>Functions</h2> - <ul> - <li>Return type and modifiers on own line</li> - <li>Function name and argument list on next line</li> - <li>Opening <code>{</code> on own line (function definitions are a special case of blocks as they cannot be nested)</li> - <li>Functions not used outside translation unit should be declared and defined <code>static</code></li> - </ul> - <h2>Variables</h2> - <ul> - <li>Global variables not used outside translation unit should be declared <code>static</code></li> - <li>In declaration of pointers the <code>*</code> is adjacent to variable name, not type</li> - </ul> - <h2>Keywords</h2> - <ul> - <li>Do not use a space after the opening <code>(</code> and before the closing <code>)</code></li> - <li>Always use <code>()</code> with <code>sizeof</code></li> - </ul> - <h2>Switch</h2> - <ul> - <li>indent cases another level</li> - <li>Comment cases that FALLTHROUGH</li> - </ul> - <h2>Headers</h2> - <ul> - <li>Place system/libc headers first in alphabetical order<ul> - <li>If headers must be included in a specific order comment to explain</li> - </ul></li> - <li>Place local headers after an empty line</li> - <li>When writing and using local headers<ul> - <li>Do not use <code>#ifndef</code> guards</li> - <li>Instead ensure they are included where and when they are needed</li> - <li>Read <a href="https://talks.golang.org/2012/splash.article#TOC_5.">https://talks.golang.org/2012/splash.article#TOC_5.</a></li> - <li>Read <a href="http://plan9.bell-labs.com/sys/doc/comp.html">http://plan9.bell-labs.com/sys/doc/comp.html</a></li> + <li>Tabs for indentation; space for alignment</li> + <li>C braces break style: Allman when it’s for grouping (ie. C if-else blocks), K&R when the braces are mandatory (ie. C function definition)</li> + <li>When using <code>includes</code> or similar, have them sorted (so there is deduplication) and grouped at the start of the file</li> + <li>Line-lenght:<ul> + <li>Code: 80 soft-limit, 100 hard-limit</li> + <li>Text: 80 hard-limit, expect when non-breakable (like URLs)</li> </ul></li> - </ul> - <h2>User Defined Types</h2> - <ul> - <li>Do not use <code>type_t</code> naming (it is reserved for POSIX and less readable)</li> - <li>Typedef structs</li> - <li>Do not typedef builtin types</li> - <li>Capitalize the type name</li> - <li><p>Typedef the type name, if possible without first naming the struct</p> -<pre><code>typedef struct { - double x, y, z; -} Point; -</code></pre></li> - </ul> - <h2>Line Length</h2> - <ul> - <li>Keep lines to reasonable length (current debate as to reasonable)</li> - <li>If your lines are too long your code is likely too complex</li> - </ul> - <h2>Tests and Boolean Values</h2> - <ul> - <li>Do not test against <code>NULL</code> explicitly</li> - <li>Do not test against <code>0</code> explicitly</li> - <li>Do not use <code>bool</code> types (stick to integer types)</li> - <li><p>Assign at declaration when possible</p> -<pre><code>Type *p = malloc(sizeof(*p)); -if (!p) - hcf(); -</code></pre></li> - <li><p>Otherwise use compound assignment and tests unless the line grows too long</p> -<pre><code>if (!(p = malloc(sizeof(*p)))) - hcf(); -</code></pre></li> - </ul> - <h2>Handling Errors</h2> - <ul> - <li><p>When functions <code>return -1</code> for error test against <code>0</code> not <code>-1</code></p> -<pre><code>if (func() &lt; 0) - hcf(); -</code></pre></li> - <li>Use <code>goto</code> to unwind and cleanup when necessary instead of multiple nested levels</li> - <li><code>return</code> or <code>exit</code> early on failures instead of multiple nested levels</li> - <li>Unreachable code should have a NOTREACHED comment</li> - <li>Think long and hard on whether or not you should cleanup on fatal errors</li> - </ul> - <h2>Enums vs #define</h2> - <ul> - <li><p>Use enums for values that are grouped semantically and #define otherwise.</p> -<pre><code>#define MAXSZ 4096 -#define MAGIC1 0xdeadbeef - -enum { - DIRECTION_X, - DIRECTION_Y, - DIRECTION_Z -}; -</code></pre></li> + <li>Compacting: do it if it fits the soft-limit</li> + <li>main function is defined at the end of the file and functions are grouped by topic, preferably by reversed-order of execution (scripting languages habit).</li> + <li>Functions to be used outside of their defining file should be put in a header. Make them private otherwise. This allows a clean and well-documented API.</li> + <li>Documentation is mandatory for the API and must be reachable to where they are used. (ie. external for commands/networking, internal for functions)</li> + <li>Design with extensibility in mind (so avoid booleans, test against sucess rather than error, structs are friends, …)</li> </ul> </main> <!--#include file="/templates/en/footer.html" -->