web-dev-qa-db-fra.com

La taille des pointeurs varie-t-elle en C?

Doubles possibles:
La taille des pointeurs peut-elle varier en fonction de ce qui est pointé?
Y at-il des plates-formes où les pointeurs vers différents types ont des tailles différentes?

Est-il possible que la taille d'un pointeur sur un float dans c diffère d'un pointeur sur int? Après l'avoir essayé, j'obtiens le même résultat pour toutes sortes de pointeurs.

#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("sizeof(int*): %i\n", sizeof(int*));
    printf("sizeof(float*): %i\n", sizeof(float*));
    printf("sizeof(void*): %i\n", sizeof(void*));
    return 0;
}

Quelles sorties ici (OSX 10.6 64bit)

sizeof(int*): 8
sizeof(float*): 8
sizeof(void*): 8

Puis-je supposer que des pointeurs de types différents ont la même taille (sur un arc bien sûr)?

27
Nils

Les pointeurs ne sont pas toujours de la même taille sur le même arc.

Vous pouvez en savoir plus sur le concept de pointeurs "proches", "lointains" et "énormes", juste à titre d'exemple d'un cas où la taille des pointeurs diffère ...

http://en.wikipedia.org/wiki/Intel_Memory_Model#Pointer_sizes

20
Johan Kotlinski

Dans les temps anciens, en utilisant par exemple Sur la plate-forme DOS, avec les compilateurs Borland C, il y avait au total (je pense) 5 modèles de mémoire qui pourraient même être mélangés dans une certaine mesure. Pour l'essentiel, vous aviez le choix entre de petits ou de grands pointeurs de données, et de petits ou de grands pointeurs de code, ainsi qu'un modèle "minuscule" dans lequel code et données avaient un espace d'adressage commun de 64 Ko.

Il était possible de spécifier des "énormes" pointeurs dans un programme construit autrement dans le modèle "minuscule". Donc, dans le pire des cas il était possible d'avoir des pointeurs de tailles différentes pour le même type de données dans le même programme!

Je pense que la norme n'interdit même pas cela, alors théoriquement un obscur compilateur C pourrait le faire même aujourd'hui. Mais il y a sans doute des experts qui pourront confirmer ou corriger cela.

11
Carl Smotricz

Les pointeurs sur les données doivent toujours être compatibles avec void*, de manière générale, ils seraient maintenant réalisés sous forme de types de même largeur.

Cette instruction n'est pas vraie pour les pointeurs de fonction, ils peuvent avoir une largeur différente. Pour cette raison, dans C99, le transfert de pointeurs de fonction vers void* correspond à un comportement non défini. 

8
Jens Gustedt

Si je comprends bien, rien dans la norme C ne garantit que les pointeurs vers différents types doivent avoir la même taille. En théorie, un int * et un float * sur la même plate-forme pourraient donc avoir des tailles différentes sans enfreindre les règles.

Il est nécessaire que char * et void * aient les mêmes exigences en matière de représentation et d'alignement, et il existe diverses autres exigences similaires pour différents sous-ensembles de types de pointeurs, mais rien ne couvre tout.

En pratique, il est peu probable que vous rencontriez une implémentation utilisant des pointeurs de tailles différentes, à moins que vous vous dirigiez dans des endroits assez obscurs. 

5
Nigel Harper

Oui, la taille d'un pointeur dépend de la plate-forme. Plus spécifiquement, la taille d'un pointeur dépend de l'architecture du processeur cible et du "bit-ness" pour lequel vous compilez.

En règle générale, sur un ordinateur 64 bits, un pointeur est généralement à 64 bits, sur un ordinateur 32 bits, à 32 bits. Il y a des exceptions cependant.

Puisqu’un pointeur n’est qu’une adresse mémoire, sa taille est toujours la même quel que soit le contenu de la mémoire qu’il pointe. Ainsi, un pointeur sur un float, un char ou un int a la même taille.

3
Johannes Rudolph

J'allais écrire une réponse disant que C99 avait diverses exigences en matière de conversion de pointeur qui garantissaient plus ou moins que les pointeurs vers les données devaient être tous de la même taille. Cependant, en les lisant attentivement, je me suis rendu compte que C99 est spécialement conçu pour permettre aux pointeurs d’être de tailles différentes pour différents types. 

Par exemple, sur une architecture où les entiers sont 4 octets et doivent être alignés sur 4 octets, un pointeur int peut être inférieur de deux bits à un pointeur char ou void. À condition que le casting fasse le changement dans les deux sens, vous pouvez jouer avec C99. Cela indique utilement que le résultat de la conversion d'un pointeur de caractère sur un pointeur int mal aligné est indéfini.

Voir la norme C99 . Section 6.3.2.3

3
JeremyP

Oui. C'est rare, mais cela se produirait certainement sur des systèmes non adressables par octets. Par exemple. un système 16 bits avec 64 Kword = 128 Ko de mémoire. Sur de tels systèmes, vous pouvez toujours avoir des pointeurs sur 16 bits. Mais un pointeur de caractère sur un caractère de 8 bits aurait besoin d'un bit supplémentaire pour indiquer les octets en octets/octets en octets dans le mot, ce qui donnerait des pointeurs de caractères 17/32 bits. 

Cela peut sembler exotique, mais de nombreux DSP passent 99, x% du temps à exécuter du code numérique spécialisé. Un DSP sonore peut être un peu plus simple s'il ne s'agit que de données 16 bits, laissant le calcul occasionnel 8 bits à émuler par le compilateur.

3
MSalters

Puis-je supposer que des pointeurs de types différents ont la même taille (sur un arc bien sûr)?

Pour les plates-formes avec un modèle de mémoire à plat (== toutes les plates-formes populaires/modernes), la taille du pointeur serait la même.

Pour les plates-formes avec modèle de mémoire segmentée, il existe souvent des types de pointeurs spécifiques à la plate-forme, de tailles différentes. (Par exemple, far pointeurs dans le DOS, puisque 8086 unités centrales ont utilisé un modèle de mémoire segmentée.) Mais ceci est spécifique à la plate-forme et non standard.

Gardez probablement à l'esprit qu'en C++, la taille du pointeur normal peut différer de la taille du pointeur à la méthode virtuelle. Les pointeurs sur les méthodes virtuelles doivent conserver des informations supplémentaires pour ne pas fonctionner correctement avec le polymorphisme. C’est probablement la seule exception à ma connaissance, qui est toujours d'actualité (étant donné que je doute qu'un modèle de mémoire segmenté puisse le récupérer).

1
Dummy00001

Le pointeur est une adresse mémoire - et devrait donc être identique sur une machine spécifique. Machine 32 bits => 4 octets, 64 bits => 8 octets.

Par conséquent, quel que soit le type de données de la chose pointée par le pointeur, la taille d'un pointeur sur une machine spécifique serait la même (car l'espace requis pour stocker une adresse mémoire serait le même).

Hypothèse: je parle de quasi-pointeurs vers les valeurs de données, le genre que vous avez déclaré dans votre question.

0
Gishu

Les pointeurs ont toujours la même taille sur la même arche, quel que soit le type de données vers lequel il pointe .. .. Sinon, des opérations telles que la conversion entre différents types de pointeurs sont inutiles et annulent beaucoup d'activités.

De nombreuses techniques de codage courantes dépendent du transtypage entre, par exemple, un pointeur vide (ou un caractère) vers différentes structures, en fonction de la taille.

Prenez même le standard printf (), il faut pouvoir prendre des pointeurs vers différents types de données. Si les pointeurs étaient de taille différente, l'implémentation de printf pourrait devenir très compliquée.

0
Prof. Falken

Il existe des plates-formes où les pointeurs de fonction ont une taille différente de celle des autres pointeurs. 

Je n'ai jamais vu plus de variation que cela. Tous les autres pointeurs doivent avoir une taille maximale (void *) car la norme exige qu'ils puissent être convertis en void * sans perte d'informations.

0
blucz