37 votes

Qu'est-ce à dire?: *(int32 *) 0 = 0;

Dans le morceau de code suivant, qu'est - *(int32 *) 0 = 0; moyenne?

void
function (void)
{
  ...

  for (;;)
     *(int32 *) 0 = 0;     /* What does this line do? */
}

Quelques remarques:

  • Le code semble ne pas être accessible, comme il y a un rapport de sortie avant que le morceau de code.
  • int32 est typedef'ed, mais vous ne devriez pas trop s'occuper d'elle.
  • Ce morceau de code est à partir d'une langue de l'exécution dans un compilateur, pour toute personne intéressée.

33voto

Scotty Bauer Points 1026

Le code est en procédant de la manière suivante:

   for (;;) // while(true)
     *(int32 *) 0 = 0; // Treat 0 as an address, de-reference the 0 address and try and store 0 into it.

Cela devrait erreur de segmentation, de pointeur null de référence.

MODIFIER

Compilé et exécuté pour de plus amples informations:

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

int main(void){
  *(int32_t *) 0 = 0;
  printf("done\n");
  return 0;
}

gcc -g null.c; ./a.out

Program received signal SIGSEGV, Segmentation fault.
0x00000000004004cd in main () at null.c:7
7         *(int32_t *) 0 = 0;

26voto

Eric Postpischil Points 36641

Depuis l'OP états, le code a été écrit par l'expérience du compilateur ingénieurs, il est possible que cela soit l'intention du code:

  • *(int32 *) 0 = 0; est reconnu par ce C de la mise en œuvre du code qui provoque le comportement non défini par la norme et connu à cette mise en œuvre illégale.
  • L' for (;;) en outre indique que ce code n'est jamais sorti.
  • Le compilateur ingénieurs de savoir que l'optimiseur de reconnaître ce code et en déduire qu'elle peut être "optimisé loin", parce que tout programme qui atteint ce code est autorisé à avoir un comportement, de sorte que l'optimiseur peut choisir de lui donner le comportement que si le code n'est jamais atteint.1

Ce type de raisonnement est possible uniquement si vous avez des connaissances spécifiques du fonctionnement interne d'une œuvre. C'est le genre de chose qu'un compilateur ingénieur peut inclure dans l'en-tête pour un C mise en œuvre, peut-être pour marquer que certains de code (comme le code après un abort appel) n'est jamais atteint. Il ne doit jamais être utilisé en programmation.


1 considérons Par exemple ce code:

if (a)
    for (;;)
        *(int 32 *) 0 = 0;
else
    foo();

Le compilateur peut reconnaître que la clause est autorisé à avoir un comportement. Par conséquent, le compilateur est libre de choisir le comportement qu'il a fait. Pour des raisons de simplicité, qu'elle choisit d'avoir le même comportement que l' foo();. Ensuite, le code devient:

if (a)
    foo();
else
    foo();

et peut être encore simplifiée:

foo();

22voto

evilruff Points 2238

En fait, ce code seg-défaillant n'explique pas pourquoi il existe =)

Je pense que c'est à l'exécution de certains MCU.. et pourquoi il est là parce que si l'exécution du programme va arriver à ce point un tel enseignement soit de lancer un logiciel de réinitialisation pour une MCU, donc le programme va être redémarré (qui est de pratique courante dans le développement embarqué) OU si MCU configuré avec chien de garde matériel, la force MCU redémarrer en raison de chien de garde matériel et de ne jamais se terminant en boucle.

Le but principal de ces constructions à invoquer une interruption qui peut être gérée soit par le système d'exploitation ou de matériel pour lancer certaines actions.

Sachant que sa x86 dépend d'un mode CPU... en Mode Réel, rien ne s'est réellement passé instantanément si il n'y a pas de chien de garde, à l'adresse 0 il y a une adresse de "diviser par 0' handler, donc si c'est un vieux MS-DOS ou incorporé x86 exécution, il va changer l'adresse de la "division par 0' gestionnaire de 0, donc dès qu'il arrive et que cette interruption n'est pas masqué CPU va sauter à la position 0:0 et sera probablement juste de redémarrer à cause d'instruction illégale.. si elle est protégée ou une VM x 86 du code, puis c'est une façon d'avertir OS ou de tout autre superviseur qu'il y a un problème dans l'exécution et le logiciel devrait être 'tué' à l'extérieur.

6voto

Sam Points 5878

for(;;) est équivalent à while(1),

*(int32 *) 0 = 0;écrit de 0 à un déréférencé pointeur null, ce qui est susceptible de causer un accident, mais le fait de ne pas tout le temps sur certains compilateurs: Écraser les filetages, *(int*)NULL = 1; problématique?

3voto

Medinoc Points 4755

C'est une boucle infinie de comportement indéfini (un déréférencement d'un pointeur null). Il est susceptible de se bloquer avec une erreur de segmentation sur *n*x ou de Violation d'Accès sur Windows.

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