kAworu's avatar

mieux vaut void que rien

publié par kAworu
il y a plus d'un an

Toi, cher lecteur assidu et passionné, tu sais pourquoi on met void comme argument d'une fonction qui n'en prend aucun dans les prototypes en C, parce que tu as appris que dans ce cas là, rien c'est beaucoup trop et void c'est rien. Pour ceux du vendredi matin difficile qui ont pas suivi (j'en vois au fond là!) voilà un petit résumé.

zathura, c'est plus void que toi

[zathura][] est un petit pdf viewer très sympathique avec des key bindings vim-like (tout ce qu'on aime quoi). Par contre, quand tu vim l'unique (!) fichier source tu trouves de quoi te donner les yeux qui piquent:

/* ... */
/* function declarations */
void init_look();
void init_directories();
void init_bookmarks();
void init_keylist();
void init_settings();
void init_zathura();
/* ... */

Goog^Wvoid est ton ami

En C il y a une différence entre les deux prototypes suivants:

int f(void);
int g();

Le premier déclare une fonction f qui n'accepte aucun arguments, alors que le second déclare une fonction g mais ne donne pas d'information de sur le type ni le nombre d'arguments que la fonction accepte. Ça veut dire qu'on peut définir la fonction g comme ça par exemple:

int
g(int answer)
{
    printf("%d\n", answer);
}

C'est pas ultra intuitif mais c'est comme ça. Mais le plus beau reste à venir.

C plouf plouf

Le C++, dans son lot « d'améliorations » a eu l'élégante idée de définir que les prototype de g et f sont équivalents. De manière générale dans du code C++ on voit des déclaration de fonction sans arguments comme ça:

int fplusplus();

Et ça ne pose aucun problème. Seulement voilà, les programmeurs chéplusplus ou Bava ou cécharpe habitués à cette syntaxe qui programment en C, ça donne ça:

/* ... */
void DebugMemory_new();

void* DebugMemory_malloc(int size, char* file, int line, char* str);

void* DebugMemory_calloc(int a, int b, char* file, int line);

void* DebugMemory_realloc(void* ptr, int size, char* file, int line, char* str);

void* DebugMemory_strdup(char* str, char* file, int line);

void DebugMemory_free(void* data, char* file, int line);

void DebugMemory_assertSize();

int DebugMemory_getBlockCount();

void DebugMemory_registerAllocation(void* data, char* file, int line);

void DebugMemory_registerDeallocation(void* data, char* file, int line);

void DebugMemory_report();
/* ... */

(la bave que je porte à ce bon vieux htop fera le sujet d'un article plus générale sur les gens aigris de coder en C, stay tuned).

ouais mais osef

Finalement c'est pas trop grave, parce que si j'écris:

/* dans le header */
int answer();

/* dans le fichier source */
int
answer()
{
    return (42);
}

Je vais pas appeler la fonction answer avec un/des argument(s). C'est pas faux (merci à robin qui remet cette phrase au goût du jour, il se reconnaitra). Maintenant si je décide de modifier la définition de la fonction answer:

/* dans le header */
int answer();

/* dans le fichier source */
int
answer(int base)
{
    return (base + 42);
}

Zut! J'ai oublié de modifier le prototype dans le header (je te vois lever les yeux, fais pas genre ça t'es jamais arrivé). Le problème c'est que maintenant tous mes call à answer sont foireux dans le sens où je donnais pas d'argument, mais ça va typecheck et compiler quand même à cause de mon prototype en carton malgré le changement de définition.

zathura, le retour

Si désormais, fort de ces connaissances, le vim te démange pour sauver zathura n'ai crainte (que neni)! Ton dévoué serviteur l'a déjà fait par amour pour toi.

Littérature

  • IBM dans le genre concis et efficace.
  • On trouve de l'info dans ce bon vieux n1256.pdf plus précisément §6.7.5.3.10 et §6.7.5.3.14.

Pour haïr un peu plus fort C++

voir ici un excellent article pour aller un peu plus loin sur le sujet. Je ne résiste pas à copy/paste la frappante conclusion pour ceux qui ont la mégaflemme du clic (ceux du fond là, toujours les mêmes):

In conclusion, do me a favor and smack the next person you see who incorrectly claims C++ is a superset of C. (Or if you meet a C++ standards committee person, just smack them.)

huit commentaires

écrire un commentaire

  1. kAworu il y a plus d'un an kAworu's avatar

    PS: Merci à Kevin et okazaki pour les encouragements à sortir mon vim pour recommencer à bloger un peu :)

  2. Rolinh il y a plus d'un an Rolinh's avatar

    Ouep, c'est pas faux ça. J'ai aussi été effrayé en voyant le code source de Zathura! Et ça fait plaisir que tu blogs de nouveau: j'apprend toujours quelque chose en lisant tes articles! Et bon, je vois bien aussi que les BSDistes void à tout va. Cela peut paraitre étrange à première vue (je pense à => (void)printf(%d, quarante_deux)) mais au final, j'avoue que ça gagne en clarté.

    Il avait compris pourquoi le dev de Zathura quand il a appliqué ton patch?

  3. kAworu il y a plus d'un an kAworu's avatar

    merci :D

    concernant le cast à void du retour de printf(3) c'est que certain compilateurs (qui ne m'ont pas permis de divulger leur identité) pondent du warning quand tu n'utilises pas les valeurs de retour des fonctions. Un cast à void permet d'éviter le warning et surtout de montrer explicitement dans le code que tu t'interesses à l'effet de bord de la fonction et non pas à la valeur produite et retournée. Un exemple peut-être plus facile avec close(2):

    int fd = open("/etc/fstab", O_RDONLY);
    /* do something with fd */
    (void)close(fd);
    

    Ici je m'en fout si close(2) échoue (parce que j'ai ouvert fd en readonly). Le cast à void montre que c'est pas un oubli, mais que le programmeur ignore volontairement le retour de close(2).

    Quoi qui en soit c'est une question de style, tout à fait facultatif bien que recommandé :)

    Concernant zathura je pense qu'il a compris parce que (1) t'appliques pas un patch sans comprendre pourquoi et (2) mode frime j'ai tout bien expliqué

  4. R3v4n il y a plus d'un an R3v4n's avatar

    Ca fait du bien de te voir bloguer à nouveau ;-) (je compte sur toi pour continuer)

    PS : j'adore quand tu parles de C++ (enfin C plouf plouf) :-P

  5. PatsyBurks il y a dix mois PatsyBurks's avatar

    I had got a desire to start my organization, however I did not earn enough of money to do that. Thank God my close dude advised to use the <a href="http://bestfinance-blog.com/topics/personal-loans">personal loans</a>. So I used the term loan and realized my desire.

  6. paper writing service il y a dix mois paper writing service's avatar

    Your data supposes to be supreme, but there’re many points to order the custom essay writing from the order essays service. This would present people an advantage to have good grades!

  7. buy custom essay papers il y a neuf mois buy custom essay papers's avatar

    Someone will hear referring to this good post and I propose to find the essay writers and buy essay moreover, it is possible to find already written essay.

  8. directory submissions service il y a trois mois directory submissions service's avatar

    No matter what kind of internet business you have got, little or great, you will require your website to have got a good publicity. You will get that utilizing the directory submissions service with article directory submission issues.

écrire un commentaire:


(utilisé pour gravatar, ne sera pas affiché)



tu peux utiliser la syntaxe markdown :)