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.
|
|||
|
```
|
|||
|
|
|||
|
|