Types de données efficaces et sécurisés en C++

38
Types de données efficaces et sécurisés en C++ Nicolas Burrus <[email protected]> Séminaire du LRDE, 25 Septembre 2002

Transcript of Types de données efficaces et sécurisés en C++

Page 1: Types de données efficaces et sécurisés en C++

Types de données efficaces et sécurisésen C++

Nicolas Burrus <[email protected]>

Séminaire du LRDE, 25 Septembre 2002

Page 2: Types de données efficaces et sécurisés en C++

Table des matières

Table des matières

Introduction ............................................................................ 3

Contexte ............................................................................... 4

Problématique........................................................................ 5

Approches existantes ........................................................... 7

Matlab - Octave ...................................................................... 8

Vigra .................................................................................... 9

Ada...................................................................................... 12

Ancienne version d’Olena ......................................................... 13

Bilan global ........................................................................... 15

Besoins et objectifs ............................................................... 16

Ce qu’on aimerait ................................................................... 17

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 1

Page 3: Types de données efficaces et sécurisés en C++

Table des matières

Que veut-on pour les types ? ..................................................... 18

Implémentation en C++ ......................................................... 19

Hiérarchie des scalaires ........................................................... 20

Organisation globale ............................................................... 21

Les opérateurs arithmétiques .................................................... 23

Les types de retour des opérations arithmétiques .......................... 27

La sécurité ............................................................................ 28

Ecrire un décorateur fonctionnel................................................. 29

Exemple de décorateur ............................................................ 30

Bilan ........................................................................................ 32

Par rapport à l’ancienne Olena .................................................. 33

Perspectives .......................................................................... 34

Conclusion ............................................................................ 36

Questions ? ........................................................................... 37

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 2

Page 4: Types de données efficaces et sécurisés en C++

Introduction

Introduction

Types de données ?

• Scalaires. Entiers, flottants

• Complexes. Réprésentation polaire, rectangulaire

• Types énumérés. Type binaire, labels

• Types vectoriels. Vecteurs, matrices

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 3

Page 5: Types de données efficaces et sécurisés en C++

Introduction Contexte

Contexte

• Bibliothèque Olena⇒ Langage C++⇒ Algorithmes génériques

• Calcul scientifique⇒ Besoin de fiabilité⇒ Besoin de performances

• Traitement d’images⇒ Chargement d’images en mémoire⇒ Utilisation intensive des types de données

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 4

Page 6: Types de données efficaces et sécurisés en C++

Introduction Problématique

Problématique

• Types builtins du C++ dangereux

. Aucune vérification d’intervalle aux affectations

i n t i = 2 5 6 ;unsigned char c = i ; / / c == 0

. Opérations arithmétiques sans contrôles

unsigned i n t i = UINT_MAX;unsigned i n t j = 5 ;unsigned long long k = i + j ; / / k == 4

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 5

Page 7: Types de données efficaces et sécurisés en C++

Introduction Problématique

• Algos génériques vis-à-vis des types de données :

template < class DataType>ResultType Sum( const Image<DataType >& ima ){

ResultType s = zero_for_Resul tType ( ) ;Image : : i t e r i ( ima ) ;

f o r _ a l l ( i )s += ima [ i ] ;

return s ;}

DataType trop petit pour la somme⇒ Quel est le type de ResultType ?

Comment écrire zero for ResultType() ?

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 6

Page 8: Types de données efficaces et sécurisés en C++

Approches existantes

Approches existantes

• Approche naive avec les builtins ne convient pas

• Autres approches intéressantes :

. Matlab/Octave

. Vigra

. Ada

. Ancienne Olena

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 7

Page 9: Types de données efficaces et sécurisés en C++

Approches existantes Matlab - Octave

Matlab - Octave

• Un seul type scalaire numérique : nombre à double précision

Bilan

⊕ Sécurité⊕ Simplicité

Occupation mémoire Temps CPU

⇒ Mal adapté au traitement d’images

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 8

Page 10: Types de données efficaces et sécurisés en C++

Approches existantes Vigra

Vigra

• Utilise uniquement les builtins du C++

• Utilise des “traits”, caractéristiques associées à un ou plu-sieurs types, par exemple :

template < class T> s t ruc t l a r g e r _ t r a i t s ;

template < > s t ruc t l a r g e r _ t r a i t s <char > {typedef short l a rge r_ t ype ;

} ;

template < > s t ruc t l a r g e r _ t r a i t s < f l oa t > {typedef double l a rge r_ t ype ;

} ;

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 9

Page 11: Types de données efficaces et sécurisés en C++

Approches existantes Vigra

Une somme générique avec Vigra s’écrit :

template < class DataType>typename v i g ra : : Numer icTrai ts <typename DataType > : : PromoteSum( const Image<DataType >& ima ){

typedef typename v i g ra : : Numer icTrai ts <typename DataType > : : Promote ResultType ;ResultType s ;Image : : i t e r i ( ima ) ;

s = v i g r a : : Numer icTrai ts <ResultType > : : zero ( ) ;f o r _ a l l ( i )s += ima [ i ] ;

return s ;}

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 10

Page 12: Types de données efficaces et sécurisés en C++

Approches existantes Vigra

Vigra - Bilan

⊕ Permet des algos génériques⊕ Simplicité

Aucune vérification des débordements Traits fastidieux à écrire (2500 lignes de code pour les builtins)

⇒ Ne remplit pas nos contraintes de sécurité

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 11

Page 13: Types de données efficaces et sécurisés en C++

Approches existantes Ada

Ada

• Vérification des débordements à l’exécution

• Peut ajouter des contraintes :

day : I n tege r range 1 . . 3 1 ;day := 32; −− Leve une except ion a l ’ execut ion

Bilan

⊕ Sécurité⊕ Contraintes

Ne permet pas de rajouter nos propres contraintes Surcoût à l’exécution

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 12

Page 14: Types de données efficaces et sécurisés en C++

Approches existantes Ancienne version d’Olena

Ancienne version d’Olena

• Nouveaux types : int u<nbits>, sfloat, ...

• Vérifications statiques

Bilan

⊕ Contrôle des types⊕ Pas de surcoût à l’exécution

Temps de compilation Typage statique trop contraignant :

i n t_u <8> i = 5 ;in t_u <8> j = 2 ;in t_u <8> k = i + j ; / / Ne compile pas d i rec tement ( i + j ) es t un in t_u <9>

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 13

Page 15: Types de données efficaces et sécurisés en C++

Approches existantes Ancienne version d’Olena

Bilan (suite)

Algos incompatibles avec les builtins

template < class T>T average ( const l i s t <T>& l ){

/ / Ne compile pas avec T == b u i l t i ntypedef typename T : : l a rge r_ t ype la rge r_ t ype ;l a rge r_ t ype sum = la rge r_ t ype : : zero ( ) ;/ / . . .

}

⇒ Utilisation lourde

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 14

Page 16: Types de données efficaces et sécurisés en C++

Approches existantes Bilan global

Bilan global

Que nous apportent ces solutions ?

• Algos génériques avec intégration des builtins⇒ Vigra

• Vérifications des données à l’exécution⇒ Ada

• Typage fort et vérifications statiques⇒ Ancienne Olena

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 15

Page 17: Types de données efficaces et sécurisés en C++

Besoins et objectifs

Besoins et objectifs

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 16

Page 18: Types de données efficaces et sécurisés en C++

Besoins et objectifs Ce qu’on aimerait

Ce qu’on aimerait

• Sécurité⇒ Contrôle des débordements

• Efficacité⇒ Occupation mémoire minimale⇒ Vitesse d’exécution optimale⇒ Version “release” sans sécurité à l’exécution

• Généricité⇒ Ecriture simple d’algos génériques⇒ Interopérabilité avec les builtins

• Extensibilité⇒ Ajout de nouveaux types aisé

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 17

Page 19: Types de données efficaces et sécurisés en C++

Besoins et objectifs Que veut-on pour les types ?

Que veut-on pour les types ?

• 1 type ⇔ une classe

. Ses variations ⇔ paramètres template

. Exemple : Entier non signé int_u

. Nombre de bits : int_u<8>

. Comportement : int_u<8,strict>

• On veut les propriétés classiques

. Opérations arithmétiques

. Conversions “naturelles”

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 18

Page 20: Types de données efficaces et sécurisés en C++

Implémentation en C++

Implémentation en C++

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 19

Page 21: Types de données efficaces et sécurisés en C++

Implémentation en C++ Hiérarchie des scalaires

Hiérarchie des scalaires

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 20

Page 22: Types de données efficaces et sécurisés en C++

Implémentation en C++ Organisation globale

Organisation globale

On cherche à orthogonaliser le code au maximum

⇒ 3 hiérarchies parallèles :

• Valeurs : rec_value

. Stockage

• Types : typetraits<T>

. Définit les caractéristiques relatives au type : larger_type , cumul_type , ...

• Opérations : optraits<T>

. Traits fonctionnels : zero() , min() , ...

Cette division permet :

• L’intégration des builtins dans 2 hiérarchies

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 21

Page 23: Types de données efficaces et sécurisés en C++

Implémentation en C++ Organisation globale

• L’écriture d’algos génériques

• Une meilleure souplesse dans le code

• Simplifications des types décorateurs⇒ Redéfinition d’une partie des classes uniquement

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 22

Page 24: Types de données efficaces et sécurisés en C++

Implémentation en C++ Les opérateurs arithmétiques

Les opérateurs arithmétiques

On veut factoriser les opérations pour tous les scalaires.

On aimerait écrire (1) :

template < class T1 , class T2>returnTypeoperator +( const rec_sca lar <T1>& lhs ,

const rec_sca lar <T2>& rhs ){

/ / value ( ) es t une methode qui renvo ie l a va leurreturn l hs . value ( ) + rhs . value ( ) ;

}

Mais on veut gérer les builtins !

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 23

Page 25: Types de données efficaces et sécurisés en C++

Implémentation en C++ Les opérateurs arithmétiques

On rajoute (2) ...

template < class T1 , class B2>returnTypeoperator +( const rec_sca lar <T1>& lhs ,

const B2& rhs ){

return l hs . value ( ) + rhs ;}

et (3) :

template < class B1 , class T2>returnTypeoperator +( const B1& lhs ,

const rec_sca lar <T2>& rhs ){

return l hs + rhs . value ( ) ;}

Aie ! Ambigü pour le compilateur.

• Exemple : int_u + int_u

. Identification à un argument template prioritaire sur la relation d’héritage⇒ (2) et (3) sont prioritaires sur (1)⇒ Conflit entre (2) et (3)

On veut mettre une contrainte sur B1 et B2 pour les limiter aux builtins.

Donnons nous une classe universelle :

template < class T>s t ruc t anyClass

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 24

Page 26: Types de données efficaces et sécurisés en C++

Implémentation en C++ Les opérateurs arithmétiques

{anyClass (T& t ) : _ ta rge t ( t ) { }T& s e l f ( ) { return _ ta rge t ; }T& _ ta rge t ;

} ;

Finalement on peut réécrire (2) (de même pour (3)) :

template < class T1 , class T2>returnType operator +( const rec_sca lar <T1>& lhs , const anyClass <T2>& rhs ){

return l hs . value ( ) + rhs . s e l f ( ) ;}

Construire une anyClass par conversion difficile⇒ plus d’ambiguité

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 25

Page 27: Types de données efficaces et sécurisés en C++

Implémentation en C++ Les opérateurs arithmétiques

Problème : le compilateur ne peut déduire T2 tout seul⇒ il faut instancier explicitement la fonction par un opérateur “proxy” global

template < class T1 , class T2>returnTypeopera tor_p lus ( const rec_sca lar <T1>& lhs ,

const anyClass <T2>& rhs ){

return l hs . value ( ) + rhs . s e l f ( ) ;}

template < class T1 , class T2>returnTypeopera tor_p lus ( const anyClass <T1>& rhs ,

const rec_sca lar <T2>& rhs ){

return l hs . s e l f ( ) + rhs . value ( ) ;}

template < class T1 , class T2>returnTypeopera tor_p lus ( const rec_sca lar <T1>& rhs ,

const rec_sca lar <T2>& rhs ){

return l hs . value ( ) + rhs . value ( ) ;}

/ / operateur g loba l proxytemplate < class T , class U>returnTypeoperator + ( const T& lhs ,

const U& rhs ){

return operator_p lus <T ,U>( lhs , rhs ) ;}

Ce code n’est écrit qu’une seule fois pour tous les sca-laires !

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 26

Page 28: Types de données efficaces et sécurisés en C++

Implémentation en C++ Les types de retour des opérations arithmétiques

Les types de retour des opérations arithmétiques

• Traits binaires pour les définir

• Les types grossissent, par exemple :int_u<8> + int_u<8> ⇒ int_u<9>

int_s<8> * int_u<8> ⇒ int_s<17>

⇒ Permet un typage fin

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 27

Page 29: Types de données efficaces et sécurisés en C++

Implémentation en C++ La sécurité

La sécurité

• Vérifications statiques si possible ...

i n t_u <7> i = 5 ;in t_u <7> j = 5 ;in t_u <8> k = i ; / / ok , on s a i t que ca ren t re ra , pas de t e s t sk = i + j ; / / ok , on s a i t que ca ren t re ra , pas de t e s t s

• ... à l’exécution sinon

i n t_u <8> i = 5 ;in t_u <8> j = 5 ;in t_u <8> k = i + j ; / / asser t ( ( i + j ) <= o p t r a i t s < in t_u <8 > >::max ( ) )

⇒ Finalement, vitesse maximale

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 28

Page 30: Types de données efficaces et sécurisés en C++

Implémentation en C++ Ecrire un décorateur fonctionnel

Ecrire un décorateur fonctionnel

• Hiérarchie de valeur : presque rien⇒ Définition des constructeurs/destructeurs⇒ Opérateurs de cast

• Hiérarchie de type : presque rien⇒ Proxy vers les caractéristiques du type décoré

• Hiérarchie d’opérations : juste les fonctions nouvelles/modi-fiées⇒ L’héritage apporte toutes les opérations par défaut

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 29

Page 31: Types de données efficaces et sécurisés en C++

Implémentation en C++ Exemple de décorateur

Exemple de décorateur

Prenons par exemple range<T,Interval,Behaviour> :

/ / h i e r a r c h i e de va leurstemplate < class T , class I n t e r v a l , class Behaviour >s t ruc t range : publ ic rec_sca lar <T , I n t e r v a l , Behaviour > {

range ( const T& lhs ) { _value = lhs ; }/ / . . . Autres cons t ruc teu rs e t operateur de cast

} ;

/ / h i e r a r c h i e de typestemplate < class T , class I n t e r v a l , class Behaviour >s t ruc t t y p e t r a i t s <range<T , I n t e r v a l , Behaviour > : publ ic t y p e t r a i t s <T > {

typedef typename t y p e t r a i t s <T > : : l a rge r_ t ype la rge r_ t ype ;/ / l e res te des typedefs proxy

} ;

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 30

Page 32: Types de données efficaces et sécurisés en C++

Implémentation en C++ Exemple de décorateur

Finalement, la hiérarchie d’opérations

/ / h i e r a r c h i e d ’ opera t ionstemplate < class T , class I n t e r v a l , class Behaviour >s t ruc t o p t r a i t s <range<T , I n t e r v a l , Behaviour > : publ ic o p t r a i t s <T > {

typedef I n t e r v a l : : re tu rn_ type i n t e r v a l _ t y p e ;s t a t i c i n t e r v a l _ t y p e min ( ) { return I n t e r v a l : : min ( ) ; }s t a t i c i n t e r v a l _ t y p e max ( ) { return I n t e r v a l : : max ( ) ; }

} ;

On peut maintenant écrire :

range< in t , bounded_s <−10 , 10 > , sa tura te > r1 = −30; / / vaut −10range<int_u8 , bounded_u <0 , 10 > , s t r i c t > r2 = 5 ;

s td : : cout < < ( r1 + r2 ) < < std : : endl ;

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 31

Page 33: Types de données efficaces et sécurisés en C++

Bilan

Bilan

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 32

Page 34: Types de données efficaces et sécurisés en C++

Bilan Par rapport à l’ancienne Olena

Par rapport à l’ancienne Olena

• Gains. Sécurité

. Types décorés - possibilité d’extension

. Intégration des builtins

. Factorisation du code

. Simplicité d’utilisation

• Problèmes conservés. Temps de compilation

. Code complexe

. Débuggage difficile

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 33

Page 35: Types de données efficaces et sécurisés en C++

Bilan Perspectives

Perspectives

• Extension, implémentation de plus de types

• Ajout de caractéristiques mathématiques⇒ Héritage conditionnel vers les structures algébriques cor-respondantes

• Amélioration de la gestion des décorateurs⇒ Meilleure intégration à la hiérarchie⇒ Plus de généricité, exemple :

s t ruc t cmp_inf : publ ic s td : : b ina ry_ func t i on <vec<N, T> , vec<N, T> , bool > {bool operator ( ) ( const vec<N, T>& lhs , const vec<N, T>& rhs ) const{ return ( l hs [ 0 ] < rhs [ 0 ] ) ; }

} ;

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 34

Page 36: Types de données efficaces et sécurisés en C++

Bilan Perspectives

i n t main ( ) {r e l a t i o n a l _ d e c o r a t o r <vec <3 , in t > , cmp_inf > v1 ;v1 [ 0 ] = 5 ;/ / . . . f i n de l ’ i n i t de v1r e l a t i o n a l _ d e c o r a t o r <vec <3 , in t > , cmp_inf > v2 ;/ / i n i t de v2

i f ( v1 < v2 ){

s td : : cout < < ‘ ‘ Youpi ! ’ ’ < < s td : : endl ;}

}

Problème : mauvaise intégration des décorateurs

⇒ On ne peut pas écrire un relational_decorator qui fonc-tionne pour tous les types.

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 35

Page 37: Types de données efficaces et sécurisés en C++

Bilan Conclusion

Conclusion

• Solution qui permet plus de choses

• Conserve un certain nombre de problèmes

• Migration d’Olena en cours

• Devrait être distribué séparément d’Olena.

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 36

Page 38: Types de données efficaces et sécurisés en C++

Bilan Questions ?

Questions ?

Types de données efficaces et sécurisés en C++, Nicolas Burrus - Séminaire du LRDE, 25 Septembre 2002 37