67 votes

Se pourrait-il que sizeof(T*) != sizeof(const T*) ?

Je me dispute avec mon patron à ce sujet. Ils disent "Oui, ils peuvent être différents."

Est-il possible que sizeof(T*) != sizeof(const T*) pour un type T ?

81voto

hvd Points 42125

Non, ils ne peuvent pas être différents. Pour une différence suffisante T1 et T2 , sizeof(T1 *) peut être différent de sizeof(T2 *) mais si T2 est juste const T1 alors :

3.9.2 Types de composés [basic.compound].

3 [...] Les pointeurs vers les versions qualifiées et non qualifiées (3.9.3) de types compatibles avec la mise en page doivent avoir les mêmes exigences en matière de représentation des valeurs et d'alignement (3.11). [...]

Et tout type T est compatible avec sa propre mise en page :

3.9 Types [basic.types]

11 Si deux types T1 et T2 sont du même type, alors T1 et T2 sont compatible avec la mise en page types. [...]


La représentation de la valeur est en relation avec la représentation de l'objet, vous ne pouvez pas avoir la même représentation de la valeur sans avoir également la même représentation de l'objet. Cette dernière signifie que le même nombre de bits est nécessaire.

3.9 Types [basic.types]

4 Le représentation des objets d'un objet de type T est la séquence de N unsigned char occupés par l'objet de type TN est égal à sizeof(T) . Le site représentation des valeurs d'un objet est l'ensemble des bits qui contiennent la valeur du type T . Pour les types trivialement copiables, la représentation de la valeur est un ensemble de bits dans la représentation de l'objet qui détermine un valeur qui est un élément discret d'un ensemble de valeurs défini par la mise en œuvre. 44

44) L'intention est que le modèle de mémoire du C++ soit compatible avec celui du langage de programmation C de la norme ISO/CEI 9899.

L'intérêt de l'exigence, la raison pour laquelle elle ne dit pas simplement que les deux types ont la même représentation d'objet, est que T * et const T * n'ont pas seulement le même nombre de bits, mais aussi que ce sont les mêmes bits en T * et const T * qui composent la valeur. Ceci est destiné à garantir non seulement que sizeof(T *) == sizeof(const T *) mais cela signifie également que vous pouvez utiliser memcpy pour copier un T * à une valeur de pointeur const T * ou vice-versa et obtenir un résultat significatif, exactement le même résultat que vous obtiendriez avec const_cast .

Les exigences en matière d'alignement fournissent également des garanties supplémentaires, mais elles sont compliquées à expliquer correctement et ne sont pas directement pertinentes pour cette question, et certains problèmes dans la norme sapent certaines des garanties prévues, donc je pense qu'il est préférable de ne pas en tenir compte ici.

8voto

Joshua Points 13231

Microchip a sorti un tel compilateur C où le sizeof(T*) était de 2 mais sizeof(const T*) était de 3.

Le compilateur C n'était pas conforme aux normes à plusieurs égards, donc cela ne dit rien sur sa validité (je soupçonne qu'il ne l'est pas et les autres réponses sont d'accord).

5voto

PkP Points 328

Hmm, c'est très ésotérique, mais je pense que théoriquement il y a pourrait être une architecture qui possède, par exemple, 256 octets de RAM à l'adresse 0 et, par exemple, quelques kilooctets de ROM à des adresses plus élevées. Et il y a pourrait d'un compilateur qui créerait un pointeur de 8 bits pour int *i parce que 8 bits sont suffisants pour contenir l'adresse de n'importe quel objet dans la zone très limitée de la RAM et tout objet mutable est bien sûr implicitement connu pour se trouver dans la zone de la RAM. Les pointeurs de type const int *i auraient besoin de 16 bits pour pouvoir pointer vers n'importe quel emplacement dans l'espace d'adressage. Le pointeur de 8 bits int *i peut être converti en un pointeur de 16 bits const int *i (mais pas vice versa), de sorte que l'exigence de coulabilité de la norme C serait satisfaite.

Mais si une telle architecture existe, j'aimerais bien la voir (mais pas écrire du code pour elle) :)

2voto

Bathsheba Points 23209

En ce qui concerne le C++ standard, ils ne peuvent pas différer. C et C++ sont similaires sur ce point.

Mais il existe de nombreuses architectures avec des compilateurs écrits pour elles qui ne suivent pas cette règle. En effet, dans ce cas, nous ne parlons pas vraiment de C++ standard, et certaines personnes pourraient soutenir que le langage n'est pas C++, mais ma lecture de votre question (avant l'ajout de l'étiquette "avocat du langage") porte davantage sur cette possibilité.

Dans ce cas, c'est possible. Vous pourriez bien constater qu'un pointeur vers la ROM (donc const) a une taille différente de celle d'un pointeur vers la RAM (const ou non const).

Si vous êtes sûr que votre code ne se retrouvera que sur un compilateur de plaintes standard, alors votre hypothèse est correcte. Si ce n'est pas le cas, alors je réfléchirais bien avant de compter sur le fait que leurs tailles sont les mêmes.

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