Dans le code suivant, *(long*)0=0;
est utilisé de concert avec l' if
de la clause, mais quel est son but?
if(r.wid*r.ht < tot)
*(long*)0=0;
Dans le code suivant, *(long*)0=0;
est utilisé de concert avec l' if
de la clause, mais quel est son but?
if(r.wid*r.ht < tot)
*(long*)0=0;
Il écrit 0 0 interprété comme l'adresse d'un long
, c'est à dire l' NULL
pointeur. Il n'est pas valide chose à faire, depuis NULL
n'est jamais une adresse à laquelle vous pouvez valablement disposer de données que votre programme peut accéder. Ce code déclenche un comportement indéfini; vous ne pouvez pas compter sur elle pour avoir un effet particulier, en général.
Cependant, souvent, ce type de code est utilisé pour forcer un segmentation fault-type de collision, ce qui est parfois pratique de tomber dans un débogueur.
Encore une fois, c'est un comportement indéfini; il n'y a aucune garantie que cela va provoquer cette anomalie, mais sur les systèmes qui ont la segmentation des défauts, le code ci-dessus est assez probable d'en générer un. Sur d'autres systèmes, elle peut faire quelque chose de complètement différent.
Si vous obtenez une erreur de segmentation, il est parfois plus pratique pour déclencher un de cette façon qu'en réglant manuellement un point d'arrêt dans le débogueur. Par exemple, si vous n'êtes pas à l'aide d'un IDE, il est souvent plus facile de taper ces quelques jetons dans le code à l'endroit désiré, qu'il est de donner à l' (textuel) de commande du débogueur, en vous précisant le code source du fichier et le numéro de ligne manuellement peut-être un peu ennuyeux.
Dans les manuels dans C, abort
est la façon délibérément planter le programme. Toutefois, lorsque vous êtes à la programmation proche du métal, vous pourriez avoir à vous soucier de la possibilité de abort
ne fonctionne pas comme prévu! La norme POSIXy mise en œuvre de l' abort
des appels getpid
et kill
(via raise
) pour livrer SIGABRT
pour le processus, qui à son tour peut entraîner l'exécution d'un gestionnaire de signal, qui peut faire ce qu'il aime. Il y a des situations, par exemple, profondément dans les entrailles de la malloc
, en réponse aux catastrophes, éventuellement contradictoire de corruption de la mémoire, où vous devez forcer un crash sans toucher la pile à tous (en particulier, sans l'exécution d'une instruction de retour, ce qui peut sauter à un code malveillant). *(long *)0 = 0
n'est pas la chose la plus folle à essayer dans ces conditions. Il ne courez toujours le risque de l'exécution d'un gestionnaire de signal, mais qui est inévitable; il n'y a aucun moyen de déclencher SIGKILL
sans faire un appel de fonction. Plus sérieusement (à mon humble avis) les compilateurs modernes sont un peu trop de chances de voir que, d'observer qu'il a un comportement indéfini, de l'effacer et de supprimer le test en tant que bien, parce que le test ne peut pas toujours être vrai, parce que personne n'aurait délibérément appeler un comportement indéfini, seraient-ils? Si ce genre de logique semble pervers, veuillez lire la VERSION du groupe de discours sur un comportement indéfini et de l'optimisation (partie 2, partie 3).
Il y a de meilleures façons d'atteindre cet objectif. De nombreux compilateurs ont aujourd'hui une valeur intrinsèque (par exemple, gcc, clang: __builtin_trap()
) qui génère une instruction machine qui est garanti pour causer une défaillance matérielle et la livraison de SIGILL
; contrairement à l'indéfini astuces avec les pointeurs, le compilateur ne pas optimiser tout cela. Si votre compilateur ne l'a pas, mais ne disposent d'inserts assemblage, vous pouvez insérer manuellement une telle instruction-c'est probablement faible niveau assez de code que le bit supplémentaire de la machine de la dépendance n'est pas une grosse affaire. Ou, vous pouvez simplement appeler _exit
. C'est sans doute le plus sûr moyen de le jouer, parce qu'il ne veut pas courir le risque de gestionnaires de signaux, et elle ne comporte aucune fonction renvoie même à l'interne. Mais cela signifie que vous n'obtenez pas un core dump.
À cause d'un programme de "sortie anormale", utilisent l' abort()
de la fonction (http://pubs.opengroup.org/onlinepubs/9699919799/functions/abort.html).
Le standard C/C++ idiome pour "si la condition X n'est pas vrai, de rendre le programme de sortie anormale" est l' assert()
macro. Le code ci-dessus serait mieux rédigé:
assert( !(r.wid*r.ht < tot) );
ou (si vous êtes heureux de les ignorer bord des cas), il lit plus proprement que:
assert( r.wid*r.ht >= tot );
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.