flanker (./12) :
Folco (./6) :
mais j'ai du mal à faire la distinction entre un nom de structure et son type... Je ne comprends pas pourquoi les deux ne sont pas liés...
Pourquoi ne pas avoir imposé directement de définir un type quand on définit une structure, par exemple, plutôt que de nommer les structures ?
C'est le cas, c'est juste que ces types (appelés "tags") ne sont pas dans le même namespace que les identifiants ordinaires. En fait [code]typedef[/code] n'a pas été pensé pour être utilisé systématiquement de la sorte. Normalement le code devrait ressembler à ça :
/* Déclaration anticipée */
struct truc;
/* Première structure utilisant un pointeur vers la seconde */
struct machin
{
void (*func) (struct truc *t);
};
/* Définition de la structure déclarée auparavant */
struct truc
{
int i;
};
int main (void)
{
}
Le code est plus simple, et ça apporte plusieurs avantages :
- c'est le style utilisé par la libc (struct tm, etc...), ainsi que POSIX (struct stat, etc...), du coup le code est plus homogène.
- comme il s'agit d'un namespace spécifique aux structs, unions et enums, on n'a plus besoin de rajouter un préfix ou un suffix ("_t"). Il est possible d'utiliser [code]struct truc truc;[/code] pour déclarer une variable "truc" du type "structure truc". Je précise en passant que le suffix "_t" est réservé par POSIX dès lors qu'on inclue un header système, l'utilisateur n'est pas censé l'utiliser pour ses types personnels, sous peine d'incompatibilité avec les futures versions du compilateur.
- en lisant du code qui déclare des variables ou des paramètres struct, on connaît directement la sémantique des opérations effectuées sans avoir besoin de chercher la déclaration du type. Autrement dit, lorsqu'on voit [code]struct truc a, b; a = b;[/code] on sait que l'affectation copie la structure de données, avec [code]truc_t a, b; a = b;[/code] on ne sait rien, ça peut être un pointeur, un int, ou autre, on ne connaît pas le coût de l'opération à priori, ni même sa sémantique. C'est un gros point faible du langage qui fait que [code]typedef[/code] n'est pas vraiment utilisable (et n'a pas été conçu) pour faire de l'encapsulation proprement.
- en C++ la gestion des tags est différente, comme l'a précisé Zeph, il n'est pas nécessaire de mettre [code]struct/class/union/enum[/code] devant chaque tag.