Le langage C est très utilisé dans l'industrie, en particulier pour développer du logiciel embarqué. Un des intérêts de ce langage est que le programmeur contrôle les ressources nécessaires à l'exécution des programmes (par exemple, la géographie de la mémoire, ou encore les allocations et libérations de cellules de la mémoire), qui de plus influent sur les performances des programmes. Des programmes C peuvent ainsi être particulièrement efficaces, mais le prix à payer est un effort de programmation. Par exemple, il peut être nécessaire d'utiliser l'arithmétique de pointeurs afin de calculer l'adresse d'une cellule de la mémoire. Cependant, le fait que le langage C laisse davantage de liberté au programmeur favorise également la présence d'erreurs à l'exécution des programmes, erreurs qui peuvent être difficiles à détecter. Le dépassement des bornes de tableaux, ou encore la non-initialisation de variables sont des exemples de telles erreurs, qui peuvent ne pas se produire dans des langages plus récents tels que Java. D'autres erreurs à l'exécution proviennent de conversions de types et plus généralement de l'absence de sûreté du typage pour C. Des solutions existent pour assurer sur du logiciel C des résultats de sûreté compa-rables à ceux garantis par les compilateurs d'autres langages plus récents. De nom-breux systèmes effectuent des analyses statiques afin de détecter des erreurs dans les programmes C, principalement en vérifiant la sûreté des accès à la mémoire. Par exemple, l'analyse statique de Ccured repose sur un système de types qui étend celui de C et permet de séparer les pointeurs selon leur usage de la mémoire (Necula et al., 2002). Ainsi, un programme C transformé par Ccured comprend soit des accès sûrs à la mémoire, soit des accès à la mémoire dont la sûreté n'est pas garantie par l'analyse statique, et pour lesquels des assertions devant être vérifiées à l'exécution des programmes sont insérées. D'autres systèmes tels que Cyclone proposent des dia-lectes plus sûrs du langage C empêchant des erreurs telles que celles détectées par Ccured de se produire (Jim et al., 2002). Plus généralement, vérifier formellement un programme consiste à le spécifier au moyen d'annotations écrites sous forme de formules logiques et à établir ensuite que le programme satisfait sa spécification, c'est-à-dire que la spécification et le programme respectent les règles d'une logique de Hoare définissant les exécutions valides de chaque instruction du langage source. Les assertions permettent d'exprimer des pro-priétés attendues du programme. Les assertions qu'il est …
[1]
Xavier Leroy,et al.
Formal Verification of a Memory Model for C-Like Imperative Languages
,
2005,
ICFEM.
[2]
George C. Necula,et al.
Proof-carrying code
,
1997,
POPL '97.
[3]
Andrew W. Appel,et al.
Separation Logic for Small-Step cminor
,
2007,
TPHOLs.
[4]
Cristiano Calcagno,et al.
Modular Automatic Assertion Checking with Separation Logic
,
2005
.
[5]
Xavier Leroy,et al.
Formal certification of a compiler back-end or: programming a compiler with a proof assistant
,
2006,
POPL '06.
[6]
Hervé Grall,et al.
Coinductive big-step operational semantics
,
2009,
Inf. Comput..
[7]
Xavier Leroy,et al.
Formal Verification of a C Compiler Front-End
,
2006,
FM.
[8]
Peter W. O'Hearn,et al.
Local Reasoning about Programs that Alter Data Structures
,
2001,
CSL.