55 votes

Pourquoi C a-t-il une distinction entre -> et.?

OK, cela n'a aucune conséquence grave, mais ça m'énerve pour un alors: Est-il une raison pour que la distinction entre l' -> et . opérateurs?

Bien sûr, la règle actuelle est qu' . des actes sur une struct, et -> agit sur un pointeur vers une struct (ou union). Mais voici comment cela fonctionne dans la pratique. Laissez - s être un struct, dont un élément x, et laissez - ps être un pointeur vers une struct de la même forme.

Si vous écrivez

s->x

le compilateur générera un message d'avertissement dans la façon de

Vous signifiait s.x. Veuillez retaper et recompiler.

Si vous écrivez

ps.x

le compilateur générera un message d'avertissement dans la façon de

Vous signifiait ps ->. x.; Veuillez retaper et recompiler.

Parce que le compilateur connaît le type des deux s et ps au moment de la compilation, il a toutes les informations dont il a besoin pour interpréter ce que le bon opérateur. Je soupçonne que ce n'est pas comme les autres mises en garde (comme un point-virgule manquant), en qui il n'y a aucune ambiguïté sur le bon correctif.

Voici donc une proposition hypothétique de la C1x comité des normes (qui ne serait jamais considérée, parce que l'ISO est un conservateur traînée):

Compte tenu de l'expression de gauche.rhs, si g est un struct ou union de type, ensuite, l'expression renvoie à l'élément de lhs nommé rhs. Si g est de type pointeur vers une struct ou union, alors ce sera interprété comme (*lhs).rhs.

Ce serait certainement nous sauver tous les temps, et de le rendre plus facile pour les gens à apprendre le C [et j'ai appris assez de C à dire avec autorité que les apprenants trouvent l' -> chose à être source de confusion ou ennuyeux.]

Il y a même des précédents, où C n'est une poignée d'autres choses. E. g., pour la mise en œuvre des raisons, les déclarations de fonction sont toujours exprimés de pointeur de fonction, de sorte qu' f(x,y) et (*f)(x,y) à la fois travailler indépendamment de si f a été déclarée comme une fonction ou d'un pointeur de fonction.

Donc, ma question: quel est le problème avec cette proposition? Pouvez-vous penser à des exemples de cas où il serait fatal de l'ambiguïté entre ps.x et s.x, ou pourquoi garder obligatoire distinction est par ailleurs utile?

37voto

Charles Bailey Points 244082

Je ne pense pas qu'il y a quelque chose de fou au sujet de ce que vous avez dit. À l'aide de . pour les pointeurs de structures serait de travailler.

Cependant, j'aime bien le fait que des pointeurs vers les structures et les structures sont traités différemment.

Il donne un certain contexte sur les opérations et des indices quant à ce qui pourrait être coûteux.

Considérons cet extrait, imaginez que c'est au milieu d'une assez grande fonction.

s.c = 99;
f(s);

assert(s.c == 99);

Actuellement, je peux dire que l' s est une struct. Je sais que ça va être copié dans son intégralité pour l'appel à la f. Je sais aussi que qui affirment ne peut pas le feu.

Si vous utilisez . avec des pointeurs vers des struct ont été autorisés, je ne sais rien de tout cela et le faire valoir peut-feu, f pourrait définir s.c (err s->c) à quelque chose d'autre.

L'autre inconvénient est qu'il permettrait de réduire la compatibilité avec le C++. C++ permet d' -> de la surcharge dans les classes pour que les classes puissent être "comme les" pointeurs. Il est important que l' . et -> se comportent différemment. "Nouveau" code C qui utilisaient . avec des pointeurs vers des structures n'aurait probablement pas acceptable que le code C++.

30voto

cletus Points 276888

Il n’ya clairement aucune ambiguïté ou la proposition n’a pu être faite. Le seul problème est que si vous voyez:

 p->x = 3;
 

vous savez que p est un pointeur, mais si vous autorisez:

 p.x = 3;
 

Dans ce cas, vous ne savez pas réellement ce qui pourrait éventuellement créer des problèmes, en particulier si vous lancez ce pointeur ultérieurement et que vous utilisez un nombre incorrect de niveaux d'indirection.

27voto

Norman Ramsey Points 115730

Une caractéristique distinctive du langage de programmation C (par opposition à son C ++ relatif) est que le modèle de coût est très explicite . Le point se distingue de la flèche car elle nécessite une référence de mémoire supplémentaire. C veille par conséquent à rendre évident le nombre de références de mémoire à partir du code source.

10voto

AndreyT Points 139512

Eh bien, si vous avez vraiment envie d'introduire ce type de fonctionnalité dans la spécification du langage C, puis dans l'ordre pour en faire un "mélange" avec le reste de la langue de la chose logique à faire serait d'étendre le concept de "décroissance" pointeur vers une struct types. Vous avez vous-même fait un exemple avec une fonction et un pointeur de fonction. La raison pour laquelle il fonctionne de cette manière est parce que le type de fonction en C désintégrations de type pointeur dans tous les contextes, sauf pour sizeof et unaires & opérateurs. (La même chose se produit à des tableaux, BTW.)

Ainsi, afin de mettre en place quelque chose de similaire à ce que vous suggérez, nous avons pu introduire le concept de "struct-à-pointeur de la décroissance", qui fonctionne exactement de la même façon que tous les autres "désintègre" en C (à savoir, tableau de pointeur de la décroissance et de la fonction de pointeur de la décroissance) de travail: lorsqu'un struct objet de type T est utilisé dans une expression, son type se décompose immédiatement au type T* - pointeur vers le début de la structure de l'objet - sauf quand c'est un opérande de sizeof ou unaire &. Une fois qu'une telle désintégration de la règle est mise en place pour les structures, vous pouvez utiliser -> de l'opérateur d'accéder à des éléments struct indépendamment de savoir si vous avez un pointeur sur struct ou de la structure elle-même sur le côté gauche. Opérateur de . serait devenu complètement inutile dans ce cas (sauf si je suis absent quelque chose), vous pourriez toujours utiliser -> et seulement ->.

Ci-dessus, encore une fois, ce que cette fonctionnalité pourrait ressembler, à mon avis, si il a été mis en œuvre dans l'esprit de C langue.

Mais je dirais (en accord avec ce que Charles a dit) que la perte de la distinction visuelle entre le code qui fonctionne avec des pointeurs vers des structures et le code qui fonctionne avec les structures elles-mêmes n'est pas exactement souhaitable.

P. S. Une évidente conséquence négative d'une telle désintégration de la règle pour les structures serait qu'en plus de l'actuelle armée de débutants d'une façon désintéressée, en estimant que "les tableaux sont juste des pointeurs constants", nous aurions une armée de débutants de façon désintéressée à croire que, "struct objets constante pointeurs". Et Chris Torek du tableau FAQ devrait être d'environ 1,5-2 fois plus grand pour couvrir les structures ainsi :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X