Vous avez quelques options:
1) Magic valeur d'erreur. Pas toujours assez bon, pour la raison que vous décrivez. Je suppose qu'en théorie pour ce cas vous pourriez retourner un NaN, mais je ne le recommande pas.
2) Définir qu'il n'est pas valide de sauter lorsque la pile est vide. Alors votre code suppose soit qu'il n'est pas vide (et qu'il ne soit pas défini si c'est le cas), soit qu'il l'affirme.
3) Modifier la signature de la fonction afin que vous puissiez indiquer le succès ou l'échec.
int pop(double *dptr)
{
if(sp > 0) {
*dptr = val[--sp];
return 0;
} else {
return 1;
}
}
document comme « En cas de succès, renvoie 0 et écrit la valeur à l'emplacement pointé par dptr sur échec, renvoie une valeur non nulle. "
Facultativement, vous pouvez utiliser la valeur de retour ou errno
pour indiquer la raison de l'échec, bien que pour cet exemple particulier, il n'y ait qu'une seule raison.
4) Passer un objet "exception" dans chaque fonction par pointeur, et lui écrire une valeur en cas d'échec. L'appelant le vérifie ou non en fonction de la manière dont il utilise la valeur de retour. Cela ressemble beaucoup à l'utilisation de "errno", mais sans qu'il s'agisse d'une valeur à l'échelle du thread.
5) Comme d'autres l'ont dit, implémentez des exceptions avec setjmp/longjmp. C'est faisable, mais nécessite soit de passer un paramètre supplémentaire partout (la cible du longjmp à effectuer en cas d'échec), soit de le cacher dans les globales. Cela rend également la gestion des ressources de style C typique un cauchemar, car vous ne pouvez pas appeler un élément qui pourrait dépasser le niveau de votre pile si vous détenez une ressource dont vous êtes responsable.
Je ne suis pas d'accord, car même si je comprends ce que vous voulez dire, je ne donnerais pas à quelqu'un venant de java/C# land la supposition que setjmp/longjmp est en quelque sorte la 'solution' où est mon exception? – Jonke
Notez que très peu de code C utilise setjmp/longjmp pour des raisons historiques. Les codes d'erreur sont les habituels. Les codes d'erreur ne sont pas très bons; le manque d'exceptions en C est une raison majeure pour laquelle les langues plus modernes sont meilleures. – Nelson
ANSI a codifié 'setjmp 'donc il est garanti de fonctionner (au moins si le compilateur est conforme à la norme), mais le commutateur de pile et la simultanéité n'ont pas été standardisés, donc il est toujours un problème pour écrire un paquet pour C (même en utilisant asm pour faire le changement de contexte) car un compilateur * pourrait * (bien que cela puisse être improbable) effectuer des optimisations et transforme qui casse les suppositions dans le paquetage des threads. – Jonke