2010-07-23 4 views
2

Je suis assez sûr que la réponse à cette question est «non, ne sois pas stupide», mais comme on dit, il n'y a pas de questions stupides (seulement des gens stupides qui leur demandent).Possibilité de lancer vers un pointeur de type donné déterminé à l'exécution en C?

Je souhaite calculer le décalage d'un tableau. J'ai un void * gérer et le sizeof(element). Je n'ai pas de pointeur x* (où x est le type de l'élément).

Y at-il un moyen de transformer le pointeur void * en pointeur donné pour que je puisse faire de l'arithmétique de pointeur en fonction de cette taille? Au moment où je lance à un char * (en supposant un char est 1 octet *), puis en multipliant la valeur sizeof par le décalage. Si je pouvais en quelque sorte lancer le pointeur, alors je pourrais juste utiliser la syntaxe du tableau, qui serait plus propre. Comme je l'ai dit, je suis sûr à 99% que ce n'est pas possible et je demande essentiellement une représentation de type langage que C n'a pas. Mais vaut une demande.

* Et je préfère ne pas parce que ce n'est pas toujours vrai.

+4

'sizeof (char)' est toujours 1, c'est garanti. – sth

+0

J'ai lu quelque part que ce n'était pas le cas. – Joe

+0

@Joe: c'est garanti par la norme que c'est. –

Répondre

4

Comme plusieurs personnes ont dit dans les commentaires, sizeof(char) est garanti à 1. La partie pertinente de la norme C99 est à la section 6.5.3.4, décrivant l'opérateur sizeof:

Lorsqu'il est appliqué à un opérande a Type char, unsigned char ou signed char, (ou une version de celui-ci qualifié ) les résultats [de l'opérateur sizeof ] est 1.

Cela signifie que la conversion void * en char * et l'ajout de N * sizeof(element) est correcte et idiomatique.

(C est typé statiquement, donc vous ne pouvez pas convertir en un type déterminé lors de l'exécution).

0

En C, la fusion est une opération de compilation uniquement dans le temps. En tant que tel, il n'est pas possible de déterminer le type réel de l'élément de tableau au moment de l'exécution.

2

Vous ne pouvez pas faire d'introspection en C, mais cela ne vous empêche pas de rien faire.

void *v = whatever; 
char *c = (char*)v; 
c[0] = stuff; 
element *e = (element*)v; 
e[42].foo = bar; 

Si vous voulez la taille arbitraire lors de l'exécution, alors je ne crois pas qu'il y ait une façon standardisée de le faire. Certains compilateurs prennent en charge:

char c[x]; 

où x est une variable, mais je ne lui ferais pas confiance sur toutes les architectures.

Vous pouvez certainement écrire quelques simples accesseurs pour vos pointeurs vers au moins séparer le pointeur-math:

void* pointerAtPos(void*p, int offset, int width) 
{ 
    return (void*)&(((char*)p)[ offset * width ]); 
} 

Méfiez-vous des address alignment.

+0

Merci. Ce dernier extrait est ce que je suis en train de faire. On dirait que c'est le seul moyen. – Joe

+0

+1 Ce dernier répond en fait à sa question. – egrunin

Questions connexes