37 votes

sizeof prenant deux arguments

Dans C. 1.3 du C++ EST (de 2003. C'est dans le C++11 EST, aussi), la norme indique une différence entre l'ISO C et C++; à savoir, pour

char arr[100];

sizeof(0, arr) retours sizeof(char*) de C, mais 100 en C++.

Je ne trouve pas de documentation pour l' sizeof prenant deux arguments. L'évidence de secours est l'opérateur virgule, mais je ne le pense pas: sizeof(arr) C est - 100; sizeof(0, arr) est sizeof(char*). Les deux sizeof(0, arr) et sizeof(arr) sont 100 en C++.

J'ai peut-être manquant le point de l'ensemble de l'EST dans ce contexte. Quelqu'un peut-il aider? Ceci est similaire à une question abordés dans '09, mais pas de celui visé à l'EST, et je ne pense pas que la bonne réponse a été donnée.


Edit: en Fait, l'EST est de parler de l'opérateur virgule. Si, pour quelque raison, (0, arr) renvoie un char* de C, mais un char[100] en C++. Pourquoi?

48voto

Nawaz Points 148870

En C, l'opérateur virgule ne produisent pas une lvalue, par conséquent, la matrice arr qui est une lvalue se désintègre en un type pointeur qui est une rvalue (dans ce cas). Donc, sizeof(0,arr) devient l'équivalent sizeof(char*), en raison de lvalue-à-rvalue de conversion.

Mais en C++, l'opérateur virgule produit une lvalue. Il n'y a pas de lvalue-à-rvalue de conversion. Donc, sizeof(0,arr) reste la même, ce qui est équivalent à sizeof(char[100]).

Par la voie, sizeof n'est pas une fonction, c'est un opérateur. Donc la suite est tout à fait valable, C++ et C, si vous imaginez printf au lieu de cout):

int a[100], b[200], c[300], d[400];
cout << sizeof(a,b,c,d) << endl;

Démo : http://www.ideone.com/CtEhn

Vous pourriez penser que j'ai passé 4 opérandes sizeof mais c'est faux. sizeof fonctionne sur le résultat de la virgule opérateurs. Et ses parce que de nombreux virgule opérateurs, vous verrez de nombreux opérandes.

4 opérandes <=> 3 virgule opérateurs; tout comme en 1+2+3+4, il y a 3 opérateurs, 4 opérandes.

Le ci-dessus est équivalente à la suivante (valable en C++0x):

auto & result = (a,b,c,d); //first all comma operators operate on the operands.
cout << sizeof (result) << endl; //sizeof operates on the result

Démo : http://www.ideone.com/07VNf

La virgule de l'opérateur qui vous fait sentir qu'il y a de nombreux arguments. Ici, la virgule est un opérateur, mais dans l'appel de fonction, la virgule n'est PAS un opérateur, il s'agit tout simplement de l'argument séparateur.

function(a,b,c,d); //here comma acts a separator, not operator.

Donc, sizeof(a,b,c,d) fonctionne sur le type du résultat de l' , opérateurs, exactement de la même manière, sizeof(1+2+3+4) fonctionne sur le type du résultat de l' + opérateurs.

Notez également que vous ne peut pas écrire sizeof(int, char, short), précisément parce que la virgule opérateur ne peut pas fonctionner sur les types. Il fonctionne sur la valeur seulement. Je pense que, sizeof est le seul opérateur en C et C++, qui peut fonctionner sur les types ainsi. En C++, il y a encore un opérateur qui peut fonctionner sur les types. Son nom est typeid.

25voto

Puppy Points 90818

En C, le tableau se décompose en un pointeur, en raison de la spécification différente de l'opérateur de virgule en relation avec les valeurs rvalues et lvalues (le seul endroit où une telle différence peut être trouvée). En C ++, le tableau reste un tableau et donne le résultat correct.

6voto

AndreyT Points 139512

C'est un opérateur virgule. Et la différence dont vous parlez n'a absolument rien à voir avec l' sizeof. La différence est vraiment dans lvalue-à-rvalue, tableau de pointeur et similaires désintégration de comportements entre les langages C et C++.

Le langage C est plutôt à la gâchette facile, à cet égard: les tableaux de décroissance de pointeurs pratiquement immédiatement (à l'exception de très peu de contextes spécifiques), qui est pourquoi le résultat de l' 0, arr expression a char * type. Il est équivalent à 0, (char *) arr.

En langage C++ tableaux préserver "ils arrayness" beaucoup plus longtemps. Lorsque utilisé dans le contexte de l' , opérateur tableaux ne sont pas à la carie de pointeurs (et lvalues ne baissent pas pour rvalues), c'est pourquoi en C++, le type d' 0, arr expression est encore char[100].

C'est ce qui explique la différence en sizeof comportement dans cet exemple. ?: - opérateur est un autre exemple d'un opérateur qui montre la différence semblable dans le délabrement de comportement, c'est à dire sizeof(0 ? arr : arr) vous donnera des résultats différents en C et C++. Fondamentalement, tout cela provient du fait que les opérateurs de C n'avez pas l'habitude de préserver la lvalueness de leurs opérandes. Beaucoup d'opérateurs peuvent être utilisés pour illustrer ce comportement.

5voto

Ce n'est pas sizeof prenant deux arguments. sizeof est un opérateur, pas une fonction.

Considérez que (0, arr) est une expression utilisant l'opérateur virgule, et tout le reste se met en place.

3voto

James Kanze Points 96599

sizeof ne pas prendre deux arguments. Mais ce n'est pas une fonction, soit, si l' (...) ne pas délimiter les arguments de la fonction, ils sont juste un la partie facultative de la syntaxe, et d'appliquer le regroupement. Lorsque vous écrivez sizeof(0, arr), l'argument sizeof est la seule expression 0, arr. Une expression unique avec un opérateur virgule, qui évalue l' l'expression à gauche de la virgule, jette sa valeur (mais pas de son effets secondaires), puis évalue l'expression à droite de la virgule, et utilise sa valeur en tant que valeur de l'expression complète.

Je ne suis pas sûr au sujet de C, mais ce pourrait être une différence entre les langues. En C++, le tableau de pointeur de la conversion n'a pas lieu, à moins que il est nécessaire; en C, si je me souviens bien, la norme dit qu'il prend toujours lieu, sauf dans certains contextes. Y compris le opérateur de sizeof. Dans ce cas, puisque l'opérateur virgule n'est pas avoir des contraintes en ce qui concerne les types de ses opérandes, l' tableau de pointeur de la conversion n'a pas lieu en C++. En C, une operatand de l'opérateur virgule n'est pas répertorié dans les exceptions, de sorte que le tableau de pointeur de la conversion a lieu. (Dans ce cas, le tableau est un opérande de l'opérateur virgule, et pas de sizeof.)

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