Tabs and Spacing
Two spaces (four is fine as well, just be consistent).
Why? Never use tabs unless strictly necessary (inside a Makefile, etc.). Tabs are inconsistent and more often than not make a mess of things online when people browse code in repositories like Github. This is the most common way people browse our code, and spaces ensure that the code is consistent and readable in any context.
Save your tabs for CircuitPython.
Naming Conventions
Learning from many of my own mistakes, these are the habits I've picked up over the years.File Names
Use all lower case letters!Why? While upper and lower case is a non-issue on Windows, it can cause endless headaches in other operating systems and build environments. Using only lower-case letters in your file names avoids this problem entirely, and your compiler will never complain that it can't find a file.
error_t pcf2129Init ( void ); void pcf2129SetCallback ( void (*pFunc)(void) ); error_t pcf2129ReadTime ( rtcTime_t *p_time ); error_t pcf2129SetTime ( rtcTime_t time ); error_t pcf2129SetInterrupt ( pcf2129_INTEvent_t eventFlags );
Why? This just makes it easier to know exactly where a function is located when it's used somewhere. You might call hundreds of functions in a single file or complex chunk of code, and it isn't always easy to track them down by memory. Appending every function with the filename or something similar (sensor name, etc.) makes things much less ambiguous.
Field/Variable Names
Flag shared fields with '_' or 'm_' and use meaningful namesstatic bool _pcf2129Initialised = false; static void (*_pcf2129Callback)(void) = NULL;
Why? It's helpful to have a clear visual queue of what's defined on a module level (fields or variables share by all functions in the file/module) and what's local and only exists on the stack.
You should also include the filename (or an abbreviation of it) in any global variables that you define like this to avoid problems debugging later when everything is linked together.
You should also include the filename (or an abbreviation of it) in any global variables that you define like this to avoid problems debugging later when everything is linked together.
Flag pointer parameters with a 'p' or 'p_' prefix
To make sure that people understand that they are working with pointers and 'references' to external memory blocks, prefix all pointer parameters with either 'p' or 'p_':
To make sure that people understand that they are working with pointers and 'references' to external memory blocks, prefix all pointer parameters with either 'p' or 'p_':
error_t pcf2129ReadTime ( rtcTime_t *p_time );
Why? Pointers allow for more efficient use of limited memory resources, but require special considerations in the code. By prefixing all pointers with a clear value, you set off an alarm bell in people's head to make sure that they understand they aren't working with a normal variable located on the local stack, etc.
Indent Style
Use whichever you prefer between Allman and K&R, just be consistent!This is highly personal, but I've always been an Allman person, where the opening brace is on a newline:
/* Allman Style */ for ( i = 0; i < length; i++ ) { buffer[i] = I2CSlaveBuffer[i]; }
Many people seem to prefer K&R (where the opening brace is on the same line as the code), but I've always found this harder to follow.
/* K&R Style */ for ( i = 0; i < length; i++ ) { buffer[i] = I2CSlaveBuffer[i]; }
Why? I just find nested loops easier to read in Allman, but this is a personal choice and the important thing is being consistent.
Page last edited April 23, 2024
Text editor powered by tinymce.