Le dépassement d'entier sur SDL_GetTicks
à l'attention des sages

La fonction SDL_GetTicks retourne un entier non signé sur 32 bits chargé de représenter le nombre de millisecondes écoulées depuis l'initialisation de la librairie SDL2. En apparence anodin, un dépassement d'entier (ou integer overflow) sur la valeur de retour de cette fonction est toutefois intéressant à relever.

Compréhension du problème

Une application SDL2 doit être exécutée de manière continue pendant 49 jours (soit 232 millisecondes) pour entrainer un dépassement d'entier sur Uint32 SDL_GetTicks(void) et provoquer la troncature du résultat. Ce cas spécifique peut prêter à sourire mais privilégier les bonnes pratiques permet de se préparer efficacement en vue de situations plus critiques.

La solution élégante proposée par Raymond Chen dans son blog se transpose facilement à un contexte SDL2. En considérant StartTime comme l'entier non signé destiné à loger le temps de départ et IntervalTime comme la durée d'attente entre chaque frame, on obtient l'expression sécuritaire SDL_GetTicks() - StartTime >= IntervalTime. Cette solution fonctionne étant donné la nature particulière des entiers non signés.

Complément d’information

L'exemple illustré sur la page Wiki officielle de la fonction SDL_GetTicks souffre d'un problème d'overflow susceptible de valider prématurément la condition currentTime > lastTime + 1000. Dans l'exemple, la valeur exprimée par currentTime a de grandes chances de se trouver supérieure au résultat de l'expression lastTime + 1000 quand celui-ci s'inscrit au-delà des capacités de l'espace de stockage disponible.

À des fins d'archivage, Le code complet (extrait du Wiki de la librairie SDL2) est mis à disposition ci-dessous :

unsigned int lastTime = 0, currentTime;
while (!quit) {
 // do stuff
 // ...

 // Print a report once per second
 currentTime = SDL_GetTicks();
 if (currentTime > lastTime + 1000) {
  printf("Report: %d\n", variable);
  lastTime = currentTime;
 }
}