8. Function Names

Function names follow this pattern:

[_]<file>_[[q]<type>]<precise_name>[_ByXxxxThread](...).
where:
[_]:

When the function is for internal use only, it is made a static function type, its prototype is NOT listed in the paired .H file, and the function name is prefixed with the “_” to make it clear in for the reader when it is called, that a call is being made to a static function.

<file>:

The name of (or an abbreviation of) the FILE they are contained in;

[q]<type>:

Only used when return type is not void; the letter ‘q’ is used when the function is a query (i.e. does not alter the object(s) it operates on). TYPE Prefix as is described for variables above. (More on this below.) (See Commands and Queries for definition of “query” and its importance.)

<precise_name>:

In the Design-by-Contract vernacular (commands & queries, a.k.a. procedures & functions):

  • commands (return void) - <precise_name> is a VERB or VERB PHRASE stating precisely what the command does.

  • queries (return a type) - <precise_name> is a NOUN or NOUN PHRASE stating precisely what the function returns.

[_ByXxxxThread]:

In a multi-threaded environment, in a function where data is shared, it is sometimes important for the reader to know which particular thread or threads are calling the function so that appropriate measures can be taken (or seen that they are indeed present or missing) that properly protects any shared data. The rule is: if data is shared among threads and reading it is not atomic to the CPU, then it will be corrupted now and then when that data is used. It must either be protected, or it must be okay for it to be corrupted (rare). How that protection is done is outside the scope of this description.

If the “thread” is an ISR, then this suffix becomes “_FromISR”.

For this same reason, functions that encapsulate threads of execution such as tasks in an RTOS end with the name “Task” or “Thread” or “Process” based on the naming used with that RTOS. Example:

_GpsTask()

This policy, as a side effect, due to increased readability and understandability: it speeds up development, as well as provides buffers against future bugs caused by the code not being correctly understood by the programmer using or modifying them.

Camel-case capitalization for non-library functions is adopted for consistency with existing source code. As a side effect, this helps the reader to recognize that the function is application specific, as opposed to library code. Library code, on the other hand, can use “Eiffel-case” (e.g. nand_qui32_computed_ecc_code()) which is also quite readable.

Comparison:

nand_qui32_computed_ecc_code(...)          /* Library */

vs

NAND_qui32ComputedEccCode(...)             /* Application */

Exception:

If this rule and/or capitalization (e.g. of a proper name that is all caps, or a well-understood acronym) ever makes the meaning of the name difficult to read, it is entire acceptable to insert an underscore (‘_’) to separate words to make it more readable. Reason: understandability (the primary purpose of having a Coding Standard at all) is senior to Policy.

Example:

SYS_qui32SYSCLKHz(...)   /* Difficult to read; slower to understand. */

changes to:

SYS_qui32_SYSCLK_Hz(...) /* Understanding is faster and clearer. */

FILE Prefix Examples:

LapTimer_DoAfterLapProcessing(...)          from file GLT.c.
PBC_qui16DistanceBetweenBreadcrumbs(...)    from file GLT_Breadcrumb.c. (P = packed)
PVenue_qdGateLatitude(...)                  from file GLT_Venue.c. (P = packed)
SessRpt_LogNewLap()                         from file SessionReport.c.
Pred2_ProcessLastGpsFix()                   from file GPS_Predictor.c. (2nd major version)
nandfs_fopen("main_image.bmp", "r")         library function, from file NAND_FileSystem.c.

TYPE Prefixes:

q<type> = query (or function) = has any return type other than void;
          a return type of void is a "command" (as opposed to a "query") and
          is designated by NOT having "q<type>" as a prefix.  <type> uses the
          TYPE Prefixes described for variables above.

Examples:

PVenue_qboolIsGateUsed(...)                 query returning bool
GpsFix_qui32SpeedOverGroundInKmh()          query returning uint32_t
Stats_RegisterCompletedLap()                command returning void
mMain_StandardRegisterNewLap()              macro (used in ISRs where calls to external
                                              functions may be undesirable due to the
                                              extended ISR prologue that the compiler will
                                              generate --- keeping the prologue short
                                              reduces interrupt latency)