J'ai trouvé cet échantillon de code dans un livre, mais je ne parviens pas à comprendre l'expression dans la déclaration Printf. et ce programme compile avec succès donner une sortie à 4. Veuillez conseiller ...
void main(){ unsigned char c; typedef struct name { long a; int b; long c; }r; r re = {3,4,5}; r *na=&re; printf("%d",*(int*)((char*)na + (unsigned int ) & (((struct name *)NULL)->b))); }
3 Réponses :
vous DÉRÉFERENGE que le pointeur, qui est pratiquement Je pense que votre code pourrait ne pas être conforme standard (voir Cette réponse pour une certaine argumentation; il pourrait y avoir des machines hypothétiques et des implémentations C où re code> est une variable locale de type
R code>, c'est-à-dire un nom
struct code>; Il est généralement alloué sur le pile d'appels . P>
na code> est un pointeur sur
re code>. p>
(non signé INT) & (((((((nom de structure *) null) -> b) code> pourrait être Comportement non défini (mais je ne suis pas sûr), mais la plupart des compilateurs compileraient que les octets de décalage - de champ
B code> (comme
offsetof < / Code> fait, voir offsetof (3) ). Sur ma machine qui pourrait être 8. p>
(char *) na + code> Le décalage ci-dessus est souvent la même adresse que
& re.b code> p> p>
& re.b code> p>
null code> n'est pas un mot tout zéro-bits, je ne sais pas de telles implémentations), mais Sur toutes les machines que je connais, il devrait imprimer la valeur du champ
re.b code> p>
merci@basile .... Permet de rester aux machines que nous savons à propos de ... :)
@HIMANSHUSOURAV: C-FAQ.com/Null/MachExamp.html Just pour que vous sachiez Quelques machines supplémentaires ;-)
@DEduplicator: Mais ces anciennes machines XXème siècle n'existent que dans les musées!
Juste à propos de. C'est pourquoi on peut ignorer un pointeur nul-zéro-zéro-nul-pointeur dans la pratique, principalement. L'UB dans le pointeur-arithmétique cependant, qui peut toujours vous mordre sur des machines modernes, selon (principalement) sur votre implémentation.
permet de commencer à partir de la dernière ligne: permet d'interpréter: p> est en réalité casting & (((( nom *) NULL) -.> b) code> dans un
unsigned int code> p>
& (((nom struct *) NULL) -> b) est l'adresse (il donne un pointeur vers): p>
(( (struct name *)NULL)->b )
Sachez que cette construction invoque l'UB cependant.
@Deduplicator est (((nom de structure *) null) -> B) code> comportement non défini? Cela semble vraiment bien défini pour moi. Pouvez-vous me signaler à un lien qui le spécifie?
@Mmarksegal Great Explication ... merci beaucoup ...
@Mmarksegal: Cela fait du pointeur-arithmétique sur un pointeur NULL, qui est simplement illégal. L'arithmétique du pointeur n'est défini que pour les pointeurs à un objet valide, et uniquement s'il ne s'échappe pas au-delà des limites de l'objet sous-jacent (le pointeur passé d'un objet est explicitement autorisé à).
@Mmarksegal: Ce peut être un comportement non défini non spécifié, même s'il travaille pratiquement partout.
@BasileSarTaryNketch Oui, vous êtes correct. Merci d'avoir fait remarquer cela.
Le code:
(unsigned int ) & (((struct name *)NULL)->b))
Techniquement, le code est pas i> Derefenrencing the null code> pointeur. Mais je pense toujours que c'est un comportement indéfini.
@BasileSelaTaryNkevitch j'ai commencé une nouvelle question pour savoir si cela est réellement ub bien que lors de la première lecture de C11, il ne semble pas beau
Vous savez
principal code> a un type de retour de
int code> in c (et c ++)?
Ce programme exact a été posté il y a 3 ans, je suppose que c'est un livre commun!