140 lines
5.7 KiB
Markdown
140 lines
5.7 KiB
Markdown
## Coding Style
|
||
Le code ne doit pas seulement être "correct" et "performant". Il doit être aussi
|
||
lisible et compréhensible par un autre être humain.
|
||
|
||
La meilleure façon d'écrire du code lisible est de choisir un style cohérent, et de
|
||
s'y tenir.
|
||
|
||
La suite est un ensemble de conseils. Vous pouvez suivre le ["K&R style"](http://www.cas.mcmaster.ca/~carette/SE3M04/2004/slides/CCodingStyle.html)
|
||
(de Brian Kernighan et Dennis Ritchie) qui ont créé le langage C, ou le style [GNU](https://www.gnu.org/prep/standards/standards.html#Writing-C).
|
||
|
||
### Un exemple
|
||
```c
|
||
|
||
/** @brief Reverse the characters of src into dst.
|
||
* @param src the input string to reverse
|
||
* @param dst the reversed string
|
||
* @return the length of src
|
||
*/
|
||
size_t strreverse(char* dst, const char* src) {
|
||
assert(dst && src); // neither parameter should be NULL
|
||
assert(dst != src); // we can’t reverse a string into itself
|
||
size_t len = strlen(src);
|
||
for (size_t pos = 0; pos != len; ++pos) {
|
||
dst[pos] = src[len - pos - 1];
|
||
}
|
||
dst[len] = 0;
|
||
return len;
|
||
}
|
||
```
|
||
|
||
- noms de variables courts et parlants,
|
||
- utilisation des types du C pour fournir des informations
|
||
sur les arguments `const char *`,
|
||
- utlisation des types utilisés par les librairies
|
||
standards (`strlen` renvoie un `size_t`),
|
||
- utilisation des fonctions standards,
|
||
- conforme aux conventions des librairies standards (nom de fonction, ordre des arguments),
|
||
- une description brève de la fonction,
|
||
- utilisation d'`assert` pour tester des pre-conditions.
|
||
|
||
La règle d'or est d'être cohérent !
|
||
|
||
#### Formatage
|
||
- choisir une indentation et s'y tenir. 4 espaces est un standard,
|
||
- passer à la ligne pour séparer les sections logiques de votre programme,
|
||
- éviter les longues lignes. 80 caractères est une limite commune,
|
||
- soyez consistant avec les accolades et les blocs,
|
||
- soyez consistant avec les espaces entre opérateurs,
|
||
- les noms de fonctions doivent être clairs et concis. Le nom doit être suffisant pour
|
||
comprendre le rôle d'une variable/fonction/strucutre.
|
||
|
||
#### Commentaires
|
||
Commenter son code est une bonne idée. Mais trop de commentaires en est une mauvaise.
|
||
- le code doit être lisible,
|
||
- commenter ce qui n'est pas triviale,
|
||
- commenter chaque fonction sur ce qu'elle fait, ses paramètres, et ce qu'elle
|
||
retourne. On peut utiliser le standard de Doxygen.
|
||
- s'il y a plusieurs fichiers sources, écrire un commentaire au début du fichier
|
||
pour expliquer son rôle.
|
||
|
||
#### Divers
|
||
- vérifier les retours d'erreurs,
|
||
- éviter les variables globales, à moins que ce ne soit indispensable,
|
||
- utiliser systématiquement un fichier d'entête avec les signatures de
|
||
vos fonctions,
|
||
- utiliser `errno.h` (appels systèmes, fonctions standards).
|
||
|
||
|
||
|
||
exemple avec l'appel système `write` :
|
||
```
|
||
ERRORS
|
||
These functions shall fail if:
|
||
|
||
EAGAIN The file is neither a pipe, nor a FIFO, nor a socket, the O_NONBLOCK flag is set for the file descrip‐
|
||
tor, and the thread would be delayed in the read operation.
|
||
|
||
EBADF The fildes argument is not a valid file descriptor open for reading.
|
||
|
||
EBADMSG
|
||
The file is a STREAM file that is set to control-normal mode and the message waiting to be read in‐
|
||
cludes a control part.
|
||
|
||
EINTR The read operation was terminated due to the receipt of a signal, and no data was transferred.
|
||
|
||
EINVAL The STREAM or multiplexer referenced by fildes is linked (directly or indirectly) downstream from a
|
||
multiplexer.
|
||
|
||
EIO The process is a member of a background process group attempting to read from its controlling termi‐
|
||
nal, and either the calling thread is blocking SIGTTIN or the process is ignoring SIGTTIN or the
|
||
process group of the process is orphaned. This error may also be generated for implementation-defined
|
||
reasons.
|
||
|
||
EISDIR The fildes argument refers to a directory and the implementation does not allow the directory to be
|
||
read using read() or pread(). The readdir() function should be used instead.
|
||
|
||
EOVERFLOW
|
||
The file is a regular file, nbyte is greater than 0, the starting position is before the end-of-file,
|
||
and the starting position is greater than or equal to the offset maximum established in the open file
|
||
description associated with fildes.
|
||
|
||
The pread() function shall fail if:
|
||
|
||
EINVAL The file is a regular file or block special file, and the offset argument is negative. The file offset
|
||
shall remain unchanged.
|
||
|
||
ESPIPE The file is incapable of seeking.
|
||
|
||
The read() function shall fail if:
|
||
|
||
EAGAIN The file is a pipe or FIFO, the O_NONBLOCK flag is set for the file descriptor, and the thread would
|
||
be delayed in the read operation.
|
||
|
||
EAGAIN or EWOULDBLOCK
|
||
The file is a socket, the O_NONBLOCK flag is set for the file descriptor, and the thread would be de‐
|
||
layed in the read operation.
|
||
|
||
ECONNRESET
|
||
A read was attempted on a socket and the connection was forcibly closed by its peer.
|
||
|
||
ENOTCONN
|
||
A read was attempted on a socket that is not connected.
|
||
|
||
ETIMEDOUT
|
||
A read was attempted on a socket and a transmission timeout occurred.
|
||
|
||
These functions may fail if:
|
||
|
||
EIO A physical I/O error has occurred.
|
||
|
||
ENOBUFS
|
||
Insufficient resources were available in the system to perform the operation.
|
||
|
||
ENOMEM Insufficient memory was available to fulfill the request.
|
||
|
||
ENXIO A request was made of a nonexistent device, or the request was outside the capabilities of the device.
|
||
```
|
||
|
||
|