2017-05-17 3 views
1

Dans le code source ci-dessous, quelqu'un pourrait expliquer le rationnel (pourquoi est-il bonne pratique de programmation à typedef la structure _lwm2m_object_t avec le nouveau nom lwm2m_object_t? Tout ce qu'il fait est de supprimer le trait de soulignement? Pourquoi un trait de soulignement utilisé dans la première instance?pourquoi utiliser un trait de soulignement pour une structure dans c?

typedef struct _lwm2m_object_t lwm2m_object_t; 

typedef uint8_t (*lwm2m_read_callback_t) (lwm2m_uri_t * uriP, char ** bufferP, int * lengthP, lwm2m_object_t * objectP); 
typedef uint8_t (*lwm2m_write_callback_t) (lwm2m_uri_t * uriP, char * buffer, int length, lwm2m_object_t * objectP); 
typedef uint8_t (*lwm2m_execute_callback_t) (lwm2m_uri_t * uriP, char * buffer, int length, lwm2m_object_t * objectP); 
typedef uint8_t (*lwm2m_create_callback_t) (lwm2m_uri_t * uriP, char * buffer, int length, lwm2m_object_t * objectP); 
typedef uint8_t (*lwm2m_delete_callback_t) (uint16_t id, lwm2m_object_t * objectP); 
typedef void (*lwm2m_close_callback_t) (lwm2m_object_t * objectP); 


struct _lwm2m_object_t 
{ 
    uint16_t     objID; 
    lwm2m_list_t *   instanceList; 
    lwm2m_read_callback_t readFunc; 
    lwm2m_write_callback_t writeFunc; 
    lwm2m_execute_callback_t executeFunc; 
    lwm2m_create_callback_t createFunc; 
    lwm2m_delete_callback_t deleteFunc; 
    lwm2m_close_callback_t closeFunc; 
    void *     userData; 
}; 
+0

Cela supprime le besoin d'utiliser 'struct' partout où le type est utilisé. Le trait de soulignement est pour éviter les conflits de noms entre le nom non typé et le nom typé – Toby

+1

Je ne pense pas que ce soit une bonne idée. A) c'est une violation standard. Tous les identifiants dans les espaces de noms de balises et de balises commençant par un trait de soulignement sont réservés, B) ils inutilement encombrent votre espace de noms global. Inutilement, car vous pouvez utiliser le même nom pour votre balise struct et pour votre typedef ('typedef struct foo foo;') - une convention que C++ a même intégrée dans le langage. – PSkocik

+0

"Tous les identifiants dans la portée de fichier et les espaces de noms de tags commençant par un trait de soulignement sont réservés" - U wot? Pas assez. – Bathsheba

Répondre

5

En fait, si vous utilisez

typedef struct lwm2m_object_t lwm2m_object_t; 

struct lwm2m_object_t { 
// 
} 

Il sera toujours permis par C. En effet, les noms de structure et les identificateurs de typedef ont des espaces de noms. Veuillez voir Why doesn't ANSI C have namespaces? pour plus d'informations sur les espaces de noms en C.

Cependant, de nombreux utilisateurs professionnels évitent cela et utilisent des noms différents pour les structures et les typedefs. MISRA interdit également cela.

Règle 5.6 (consultatif): Aucun identifiant dans un espace de nom doit avoir la même orthographe comme identifiant dans un autre espace de nom, à l'exception des membres la structure et les membres du syndicat.[MISRA C 2004]

L'utilisation du trait de soulignement est juste une convention que certaines personnes suivent. Vous pouvez suivre d'autres conventions, par ex.

typedef struct sTag_lwm2m_object_t lwm2m_object_t; 

struct sTag_lwm2m_object_t { 
// 
} 

https://en.wikipedia.org/wiki/MISRA_C

+0

Peut-être inclure un lien vers ce que MISRA est? – Bathsheba

+0

Je n'ai pas pu résister. Ajout d'une citation, et avoir un upvote. – Bathsheba

0

Un underscore est utilisé à des fins différentes par toute personne ou équipe en savoir plus dans ce answer, en particulier le paragraphe qui se consacre à

Je vois habituellement ceci:..

typedef struct lwm2m_object lwm2m_object_t; 

où on va ajouter un _t au nom de la structure, indiquant au lecteur qu'il s'agit d'un nom typedef'ef.

1

écriture typedef struct _lwm2m_object_t lwm2m_object_t; signifie que vous n'avez pas besoin d'écrire le struct _lwm2m_object_t plus bavard quand vous voulez faire référence au type struct, mais vous pouvez utiliser lwm2m_object_t directement à la place. Il économise la frappe et peut rendre le code source plus clair.

Préfixer le nom réel struct avec un seul _ est une convention qui a grandi au fil des ans. Et beaucoup de gens utilisent _t comme suffixe pour désigner un type.

Mais quelques petites choses à noter:

  1. Ne jamais utiliser un à double underscore, comme formellement le comportement à faire qui est non défini. Ne commencez pas un type avec un seul trait de soulignement suivi d'une lettre majuscule. Encore une fois, ces noms de types sont réservés.

  2. explicitement votre Posix interdit mettre fin à votre propre type avec _t, mais notez que norme C permet.

De nombreux programmeurs C expérimentés trouvent (3) répugnant et l'ignorent. (Je fais.)

+0

La convention de double underscore est aussi odieuse, pour être parfaitement honnête. Et beaucoup de programmeurs C ignorent * ça * aussi. Différents niveaux de soins pour la portabilité, je suppose. – StoryTeller

+0

@StoryTeller: Je pense que c'est vilain car il * pourrait * se heurter à des macros définies à loisir par l'implémentation de votre bibliothèque standard C. (Je ne l'autorise pas dans ma base de code.) – Bathsheba

+0

La probabilité de conflit avec la bibliothèque standard n'est pas plus grande que celle de POSIX, si on la regarde honnêtement. Je doute fortement que '__mycompany_mymodule_mycomponent_hiddenfeature' se heurtera à quoi que ce soit dans la bibliothèque standard. – StoryTeller

0

par lui-même, le underscore n'a pas de sens intrinsèque, il crée simplement un identifiant distinct pour le nom de la balise par rapport au nom de typedef. Vous pouvez obtenir le même résultat avec

typedef struct foo fooType; 

noms de Tag occupent un espace de noms différent des identificateurs ordinaires, de sorte que vous pouvez écrire

typedef struct foo foo; 

que certains considèrent comme source de confusion. Je ne sais pas - le nom du tag est désambiguïsé par la présence du mot clé struct (ou union ou enum).

Vous devriez pas utiliser les traits de soulignement dans vos identifiants - identificateurs avec deux traits de soulignement ou un underscore suivi d'une lettre majuscule sont toujours réservés à la mise en œuvre de toute utilisation, tout en identifiant avec un underscore leader unique sont réservés à les espaces de noms ordinaires et de tags.

Vous pouvez utiliser un trailing pour le même Souligner effet

typedef struct foo_ foo; 

et satisfaire tout le monde.