2009-09-24 10 views
5

d'ouverture du codebase Postgres, je vois qu'une grande partie du code C est écrit en ayant des pointeurs avec la notation -> de telle sorte que:C et notation pointeur

(foo)->next = 5; 

Je sais que la notation de pointeur a les niveaux de préséance, tels que -> = (* foo). et n'est pas la même chose que * foo.

Cependant, cela signifie-t-il quelque chose lorsque les parenthèses sont en dehors du nom de la variable et décrivent l'adresse de next ou est-ce simplement une convention qui est endémique à un style de codage?

Répondre

6

C'est une convention de codage que je n'ai jamais vue auparavant.

Mais cela ne change rien.

(foo)->next = 5; 

est exactement équivalent à

foo->next = 5; 
+0

Génial, merci. C'est ce que je pensais, et je l'ai trouvé particulièrement étrange car il était partout dans le code. – mduvall

+1

Pour développer cela, la raison pour laquelle vous utiliseriez cette construction est comme une ceinture de sécurité au cas où foo est une macro. C'est la même raison pour laquelle certains guides de style C (par exemple, FreeBSD) suggèrent que toutes les déclarations de retour soient de la forme return (x); au lieu de simplement renvoyer x; – Benno

+1

Bien que si 'foo' était une macro, il serait sage de l'avoir entièrement entre parenthèses, par ex. '#define foo (blargity-> blah)' –

1

Cela n'a aucun sens. Les parenthèses n'ont aucun effet puisque l'expression à l'intérieur d'elles est si simple. C'est essentiellement

(*(foo)).next = 5; 

Ce qui, comme vous pouvez le voir, est un ensemble de parenthèses étrangères. Si c'est ce que fait le projet, allez-y. Sinon, je pense que ça a l'air plutôt affreux, alors j'essaierais de ne pas l'utiliser.

+0

Voulez-vous dire ''(* (foo)). next = 5;''? –

+0

Oh. Droite. Au moins maintenant, j'ai l'impression qu'il y a une raison pour laquelle je ne peux pas me concentrer sur mes devoirs. Merci de l'avoir signalé, et merci à Robert pour le réparer. –

2

Il est une convention de codage pour la sécurité.

Dans un code simple, où foo est juste un pointeur, les parenthèses sont redondantes.

(foo)->next = 5; 

Cependant, considérer s'il y a ou était la chance que foo peut être définie par une macro il est donc une expression plus complexe.

Dans ce cas, les parens peuvent être nécessaires pour éviter une erreur de compilation ou, pire, pour éviter une priorité incorrecte. Imaginez si elle traduit une expression laide comme:

(++get_foo())->next = 5; 

ou une distribution commune:

((db_record*)foo_ptr)->next = 5; 

Quelque chose à garder à l'esprit avec le code idiomatiques C est que les macros sont souvent utilisées comme un mécanisme d'abstraction pour des choses que nous pourrions faire plus explicitement dans d'autres langues ;-)

+0

Toute macro qui _n'est pas_ parent de son extension est un problème. À mon humble avis, il devrait être le travail de la macro pour assurer sa propre sécurité d'utilisation, pas le travail du macro-appelant. –

Questions connexes