STYLE: make rules more granular and consistent, add examples #156

Open
trinity wants to merge 6 commits from style-c into main
Showing only changes of commit 790b12fb40 - Show all commits

68
STYLE
View File

@ -16,13 +16,28 @@ Use
if !(argc < 0) { usage(program_name); }
This applies to C switch cases, as well:
This applies to C switch statements and cases and Rust match statements, as
well:
switch (value) { /* aligning stuff to make it easier to read is fine */
case possibility: variable = foo; break;
default: variable = NULL; break;
}
switch (value) {
case possibility:
statement;
break;
case default:
statement;
break;
}
emma marked this conversation as resolved Outdated

This should just be default: (so, sed 34s:case ::); as-is this is a syntax error.

This should just be `default:` (so, `sed 34s:case ::`); as-is this is a syntax error.
match result {
Ok(n) => variable = n,
Err(e) => error = e,
}
1. Braces in control flow where their inclusion is left optional in C:
if (condition) { statement; }
@ -114,24 +129,24 @@ Use
use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE };
14. One more level of indentation for match arms and switch cases.
15. Alphabetic sorting, where applicable:
14. Alphabetic sorting, where applicable:
use std::io::{ BufWriter, Read, Write, stderr, stdin, stdout }
16. In Rust, use the to_owned() method on string types (str, OsStr, CStr, etc.)
15. In Rust, use the to_owned() method on string types (str, OsStr, CStr, etc.)
and the to_string() method on other types.
Avoid
=====
0. Heap memory allocation [0].
16. Function pointers [0].
1. Using too much nested logic (within reason).
17. Heap memory allocation [0].
2. Too many levels of dereferences [0]:
19. Using too much nested logic (within reason).
20. Too many levels of dereferences [0]:
/* do not do this */
for (size_t i = 0; i < sizeof a / sizeof *a; ++i) {
@ -143,40 +158,38 @@ Avoid
if (s->id == MATCH) { s->val = 0; }
}
3. Using C preprocessor macros; the fewer, the better [0].
21. Using C preprocessor macros; the fewer, the better [0].
4. The exit(3p) and std::process::exit() functions; returning from the main
22. The exit(3p) and std::process::exit() functions; returning from the main
function skips a system call.
Do Not Use
==========
0. Function pointers [0].
23. More than the length of one printed page for a function [0].
1. More than the length of one printed page for a function [0].
24. Recursion, as its complex and can unexpectedly overflow the stack [0].
2. Recursion, as its complex and can unexpectedly overflow the stack [0].
3. Any functionality not in the POSIX C specification and language features not
25. Any functionality not in the POSIX C specification and language features not
in C99.
4. Do-while loops, as theyre unique to C and confusing for casual programmers.
26. Do-while loops, as theyre unique to C and confusing for casual programmers.
5. Labels and goto statements; use sensible flow control [0].
27. Labels and goto statements; use sensible flow control [0].
6. Pointer arithmetic, as it tends to be confusing and unnecessary; use
28. Pointer arithmetic, as it tends to be confusing and unnecessary; use
index-reference patterns like &p[1] instead of p + 1. &p[n] is the address at
p + sizeof p * n, not p + n, like pointer arithmetic suggests.
7. C struct bitfields in unions, to access certain bits of bigger data types,
29. C struct bitfields in unions, to access certain bits of bigger data types,
as its poorly defined in the C standards; use bit arithmetic.
8. C trigraphs.
30. C trigraphs.
9. Inclusions in C header files, to prevent multiple file inclusions.
31. Inclusions in C header files, to prevent multiple file inclusions.
10. C preprocessor variables to prevent multiple inclusions of the same file,
32. C preprocessor variables to prevent multiple inclusions of the same file,
such as:
#ifdef _FILE
@ -184,17 +197,16 @@ Do Not Use
/* file body */
#endif /* ifdef _FILE */
Instead, take the time to ensure other files arent including the any files
twice.
Instead, take the time to ensure other files arent including any files twice.
11. The gets(3p) function from <stdio.h>, as its impossible to prevent buffer
33. The gets(3p) function from <stdio.h>, as its impossible to prevent buffer
overflows when it's used; use fgets(3p) from <stdio.h>.
12. The scanf(3p) function from <stdio.h> [1].
34. The scanf(3p) function from <stdio.h> [1].
13. Any functionality not described in the latest POSIX make(1) specification.
35. Any functionality not described in the latest POSIX make(1) specification.
14. Macros which panic on failure in Rust (such as the print!() and println!()
36. Macros which panic on failure in Rust (such as the print!() and println!()
macros). Use a function and handle any errors. However, do use the eprintln!()
macro for error messages. Handling an error for writing an error message is
redundant.