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
?
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
?
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
etT2
sont du même type, alorsT1
etT2
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 Nunsigned char
occupés par l'objet de typeT
où N est égal àsizeof(T)
. Le site représentation des valeurs d'un objet est l'ensemble des bits qui contiennent la valeur du typeT
. 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. 4444) 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.
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) :)
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 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.