1
C best and worst practices
Andrew Lukin
2019, Kharkiv
2
“Only two things are infinite, the
universe and human stupidity, and
I'm not sure about the former.”
Attributed to Albert Einstein
3
Some obscure moments: ternary operator
4
Some obscure moments: ternary operator
x ? : y
from Android’s QEMU:
machine->max_cpus = machine->max_cpus ?: 1; /*
Default to UP */
https://android.googlesource.com/platform/external
/qemu/+/master/vl-android.c#3472
5
Some obscure moments: ternary operator
x ? x : y
6
Some obscure moments: ternary operator
x ? x : y
It’s ok when 1st operand contain a side effect
but with -pedantic you’ll have the following complaints from
compiler:
warning: ISO C forbids omitting the middle term of a ?:
expression
7
Some obscure moments: ternary operator
status_color = frobs < 10 ? CODE_GREEN : frobs <
15 ? CODE_YELLOW : frobs < 20 ? CODE_RED :
CODE_PURPLE;
Is it clear?
8
Some obscure moments: ternary operator
status_color = frobs < 10 ? CODE_GREEN
: frobs < 15 ? CODE_YELLOW
: frobs < 20 ? CODE_RED
: CODE_PURPLE;
At least format it like that
9
A bit more of potential mistakes
from some real driver:
if(strlen(ops->name)) {
strncpy(n->name, ops->name,
(strlen(ops->name) > 79)?79:strlen(ops->name)
);
}
10
A bit more of potential mistakes
from some real driver:
if(strlen(ops->name)) {
strncpy(n->name, ops->name,
(strlen(ops->name) > 79)?79:strlen(ops->name)
);
}
--> use strscpy(), for instance
11
Let’s remember your interview for C position
void (* signal(int __sig, void (* __func)(int))) (int)
12
Let’s remember your interview for C position
void (* signal(int __sig, void (* __func)(int))) (int)
Yes, you are right. This is from some old libc…
And can be found even now, for instance, in Microchip
sources
13
Let’s remember your interview for C position
void (* signal(int __sig, void (* __func)(int))) (int)
Uncovering the magic
14
Let’s remember your interview for C position
void (* signal(int __sig, void (* __func)(int))) (int)
Uncovering the magic
15
Let’s remember your interview for C position
void (* signal(int __sig, void (* __func)(int))) (int)
Uncovering the magic
16
Let’s remember your interview for C position
void (* signal(int __sig, void (* __func)(int))) (int)
Uncovering the magic
17
Let’s remember your interview for C position
void (* signal(int __sig, void (* __func)(int))) (int)
Uncovering the magic
18
Let’s remember your interview for C position
/* Type of a signal handler. */
typedef void (*__sighandler_t) (int);
...
extern __sighandler_t __sysv_signal (int __sig,
__sighandler_t __handler)
__THROW;
glibc developers were wise from the very beginning!
19
Memory?
free(x);
free(x); <-- crash unless you are lucky
20
Memory?
free(x);
x = NULL;
free(x); <-- NO crash
21
--oneline
for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1);
22
--oneline
for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1);
is equal to:
p=0;
while (true) {
p+=(a&1)*b;
if (a == 1) break;
...
a>>=1;
b<<=1;
}
23
Know your language
In some code review
programmer “fixed” long long to long
with comment “Misprint” ...
24
Emoji
:-!!
25
Emoji
:-!!
/* from Linux kernel
*/
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
26
Emoji
:-!!
/* Force a compilation error if condition is true, but also produce a
result (of value 0 and type size_t), so the expression can be used
e.g. in a structure initializer (or where-ever else comma expressions
aren't permitted). */
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
Maybe better to name it ...OR_ZERO()
27
Emoji
28
Best: Use coding standards
A coding standard’s purpose is to restrict use of problematic
areas of the programming language.
29
Best: Use coding standards
A coding standard’s purpose is to restrict use of problematic
areas of the programming language.
So, using coding standards prevents undefined or unspecified
behavior. And it limits the use of error-prone constructs,
such as "goto".
30
Best: Use coding standards
A coding standard’s purpose is to restrict use of problematic
areas of the programming language.
So, using coding standards prevents undefined or unspecified
behavior. And it limits the use of error-prone constructs,
such as "goto".
And using coding standards also improves the code’s
readability, maintainability, and portability. One example is
the use of “typedef” to simplify the syntax of complex
structures.
31
Best: Use coding styles
For instance, Linux kernel coding style
(remember checkpatch.pl)
● indentation
● breaking long lines and strings
● placing braces and spaces
● ...
32
Best: Use coding styles
Or GNU C coding style, for instance:
if (foo)
if (bar)
win ();
else
lose ();
33
Best: Use coding styles
Or GNU C coding style, for instance:
if (foo)
{
if (bar)
win ();
else
lose ();
}
34
Best: Use coding styles
Or GNU C coding style, for instance:
if ((foo = (char *) malloc (sizeof *foo)) == NULL)
fatal ("virtual memory exhausted");
35
Best: Use coding styles
Or GNU C coding style, for instance:
if ((foo = (char *) malloc (sizeof *foo)) == NULL)
fatal ("virtual memory exhausted");
instead, write this:
foo = (char *) malloc (sizeof *foo);
if (foo == NULL)
fatal ("virtual memory exhausted");
36
Best: Use coding styles
Вопрос на форуме:
Уменязапалпробел.Чтомнеделать?
Ответ:
настоящие_программисты_пробелами_не_пользуются
или
НастоящиеПрограммистыПробеламиНеПользуются
37
Lower complexity = Better Code
Write less code go have beer sooner
3838
Questions?
Questions?
39
Questions?
Thank_you!

C Best and Worst Practices in Embedded

  • 1.
    1 C best andworst practices Andrew Lukin 2019, Kharkiv
  • 2.
    2 “Only two thingsare infinite, the universe and human stupidity, and I'm not sure about the former.” Attributed to Albert Einstein
  • 3.
    3 Some obscure moments:ternary operator
  • 4.
    4 Some obscure moments:ternary operator x ? : y from Android’s QEMU: machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */ https://android.googlesource.com/platform/external /qemu/+/master/vl-android.c#3472
  • 5.
    5 Some obscure moments:ternary operator x ? x : y
  • 6.
    6 Some obscure moments:ternary operator x ? x : y It’s ok when 1st operand contain a side effect but with -pedantic you’ll have the following complaints from compiler: warning: ISO C forbids omitting the middle term of a ?: expression
  • 7.
    7 Some obscure moments:ternary operator status_color = frobs < 10 ? CODE_GREEN : frobs < 15 ? CODE_YELLOW : frobs < 20 ? CODE_RED : CODE_PURPLE; Is it clear?
  • 8.
    8 Some obscure moments:ternary operator status_color = frobs < 10 ? CODE_GREEN : frobs < 15 ? CODE_YELLOW : frobs < 20 ? CODE_RED : CODE_PURPLE; At least format it like that
  • 9.
    9 A bit moreof potential mistakes from some real driver: if(strlen(ops->name)) { strncpy(n->name, ops->name, (strlen(ops->name) > 79)?79:strlen(ops->name) ); }
  • 10.
    10 A bit moreof potential mistakes from some real driver: if(strlen(ops->name)) { strncpy(n->name, ops->name, (strlen(ops->name) > 79)?79:strlen(ops->name) ); } --> use strscpy(), for instance
  • 11.
    11 Let’s remember yourinterview for C position void (* signal(int __sig, void (* __func)(int))) (int)
  • 12.
    12 Let’s remember yourinterview for C position void (* signal(int __sig, void (* __func)(int))) (int) Yes, you are right. This is from some old libc… And can be found even now, for instance, in Microchip sources
  • 13.
    13 Let’s remember yourinterview for C position void (* signal(int __sig, void (* __func)(int))) (int) Uncovering the magic
  • 14.
    14 Let’s remember yourinterview for C position void (* signal(int __sig, void (* __func)(int))) (int) Uncovering the magic
  • 15.
    15 Let’s remember yourinterview for C position void (* signal(int __sig, void (* __func)(int))) (int) Uncovering the magic
  • 16.
    16 Let’s remember yourinterview for C position void (* signal(int __sig, void (* __func)(int))) (int) Uncovering the magic
  • 17.
    17 Let’s remember yourinterview for C position void (* signal(int __sig, void (* __func)(int))) (int) Uncovering the magic
  • 18.
    18 Let’s remember yourinterview for C position /* Type of a signal handler. */ typedef void (*__sighandler_t) (int); ... extern __sighandler_t __sysv_signal (int __sig, __sighandler_t __handler) __THROW; glibc developers were wise from the very beginning!
  • 19.
  • 20.
  • 21.
  • 22.
    22 --oneline for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1); is equal to: p=0; while(true) { p+=(a&1)*b; if (a == 1) break; ... a>>=1; b<<=1; }
  • 23.
    23 Know your language Insome code review programmer “fixed” long long to long with comment “Misprint” ...
  • 24.
  • 25.
    25 Emoji :-!! /* from Linuxkernel */ #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
  • 26.
    26 Emoji :-!! /* Force acompilation error if condition is true, but also produce a result (of value 0 and type size_t), so the expression can be used e.g. in a structure initializer (or where-ever else comma expressions aren't permitted). */ #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) Maybe better to name it ...OR_ZERO()
  • 27.
  • 28.
    28 Best: Use codingstandards A coding standard’s purpose is to restrict use of problematic areas of the programming language.
  • 29.
    29 Best: Use codingstandards A coding standard’s purpose is to restrict use of problematic areas of the programming language. So, using coding standards prevents undefined or unspecified behavior. And it limits the use of error-prone constructs, such as "goto".
  • 30.
    30 Best: Use codingstandards A coding standard’s purpose is to restrict use of problematic areas of the programming language. So, using coding standards prevents undefined or unspecified behavior. And it limits the use of error-prone constructs, such as "goto". And using coding standards also improves the code’s readability, maintainability, and portability. One example is the use of “typedef” to simplify the syntax of complex structures.
  • 31.
    31 Best: Use codingstyles For instance, Linux kernel coding style (remember checkpatch.pl) ● indentation ● breaking long lines and strings ● placing braces and spaces ● ...
  • 32.
    32 Best: Use codingstyles Or GNU C coding style, for instance: if (foo) if (bar) win (); else lose ();
  • 33.
    33 Best: Use codingstyles Or GNU C coding style, for instance: if (foo) { if (bar) win (); else lose (); }
  • 34.
    34 Best: Use codingstyles Or GNU C coding style, for instance: if ((foo = (char *) malloc (sizeof *foo)) == NULL) fatal ("virtual memory exhausted");
  • 35.
    35 Best: Use codingstyles Or GNU C coding style, for instance: if ((foo = (char *) malloc (sizeof *foo)) == NULL) fatal ("virtual memory exhausted"); instead, write this: foo = (char *) malloc (sizeof *foo); if (foo == NULL) fatal ("virtual memory exhausted");
  • 36.
    36 Best: Use codingstyles Вопрос на форуме: Уменязапалпробел.Чтомнеделать? Ответ: настоящие_программисты_пробелами_не_пользуются или НастоящиеПрограммистыПробеламиНеПользуются
  • 37.
    37 Lower complexity =Better Code Write less code go have beer sooner
  • 38.
  • 39.

Editor's Notes

  • #3 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #4 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #5 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #6 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #7 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #8 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #9 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #10 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #11 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #12 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #13 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #14 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #15 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #16 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #17 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #18 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #19 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #20 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #21 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #22 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #23 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #24 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #25 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #26 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #27 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #28 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #29 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #30 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #31 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #32 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #33 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #34 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #35 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #36 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #37 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element
  • #38 TEXT AND IMAGE – Headline 32pt Arial in BLACK – Body copy & bulleted text 12pt Arial Reg in GRAY; body copy not to go below 10 pt – Left-justify all text and design element