© D. Mathieu
mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique
Créé le 04/08/2000 - Dernière mise à jour : 22/08/2000
opérateur ++ préfixéBibliothèques standard (STL)
Affectation des tableaux
Dimensions des tableaux
Modification des constantes
ExceptionsException length_error levée par la classe string
Exception out_of_range levée par la classe string
Exception length_error levée par la classe vector
void Ess_01 (void)
{ int i; cout << "\nTest de preincrementation OK si valeurs egales\n\n"; i = 0; cout << "1 = " << ++i << endl; i = 0; cout << "2 = " << ++++i << endl; i = 0; cout << "3 = " << ++++++i << endl; i = 0; cout << "4 = " << ++++++++i << endl; cout << endl; } // Ess_01() |
Le compilateur g++ projet GNU Egcs-1.1.2 release ne traite pas non plus Tab1 et Tab2 comme des pointeurs vers des vecteurs, car la modification d'un des deux tableaux ne modifie pas le contenu de l'autre (lignes [2] et [3]).
Cependant, ce compilateur n'accepte que des affectations
de tableaux "de même type" : il considère que Tab1
et Tab2 sont tous deux de type char [4]. Les affectations
de deux tableaux de tailles différentes sont interdites (lignes
[4] et [5]). Il en est de même pour le cas particulier
des tableaux de caractères (ligne [6]).
void Ess_02 (void)
{ cout << "\nTest d'affectation de tableau OK" " si erreur de compilation\n\n"; char Tab1 [] = {'a',
'b', 'c', '\0'};
Tab1 = Tab2; // devrait générer une erreur de compil. [1] Tab1 [1] = '1';
// [2]
cout << "Tab1 =
" << Tab1 << endl;
cout << "Si Tab1
== Tab2, ils désignent le même objet, \n"
char Tab3 [] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', '\0'}; // Tab3 = Tab1; // génère
une erreur de compil. // [4]
char Libel1 [] = "bac";
} // Ess_02() |
constantexpression :
conditionalexpression
An integral constantexpression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), nontype template parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types. Only type conversions to integral or enumeration types can be used. In particular, except in sizeof expressions, functions, class objects, pointers, or references shall not be used, and assignment, increment, decrement, functioncall, or comma operators shall not be used."
Contrairement aux recommandations de la norme ci-dessus,
le compilateur g++ projet GNU Egcs-1.1.2 release autorise la définition
de tableau dont la taille n'est pas une constante, comme par exemple :
void Ess_03 (void)
{ cout << "\nTest de definition de tableau de taille non constante\n\n"; int i; cout << "Tapez
un entier positif : ";
char Tab1
[i];
// devrait générer une erreur de compil.
} // Ess_03() |
struct CBidon
{ int m_i; CBidon (const int i = 0) : m_i (i) {} bool operator < (const CBidon & Bidon) const { return m_i < Bidon.m_i; } }; // CBidon template <class T> T& Min (const T&
a, const T& b)
void f (void)
const CBidon CB1
(1);
Min (CB1, CB2) = CBidon
(4); // [1]
cout << "CB1.m_i
= " << CB1.m_i << '\n' // CB1.m_i = 4
} // f() |
L'instruction [1] permet de modifier la constante CB1, comme le prouve l'affichage !!!
Sommaire
void reserve(size_type res_arg = 0); |
la norme indique : "Throws: length_error if res_arg > max_size())"
Malheureusement, la fonction reserve() n'est
pas implémentée (voir fichier <g++2-/std/bastring.h>)
:
void reserve (size_type) { } |
Pour le constructeur de profil :
basic_string (size_type n, charT c, const Allocator& a = Allocator()); |
la norme indique : "Throws: length_error if n == npos". A l'exécution, le programme indique le message "Segmentation fault", affiché avant que l'exception ait pu être levée (probablement au niveau de l'allocateur)
En revanche, la fonction membre resize()
lève correctement l'exception attendue.
void f (void)
{ cout << "\nTest de l'exception length_error dans la classe string\n\n"; try { string s; s.resize (s.max_size() + 1); } catch (length_error & exc) { cerr << "exception length_error capturée; " << exc.what() << endl; } } // f() |
void f (void)
{ cout << "\nTest de l'exception out_of_range dans la classe string\n\n"; try { string s ("Coucou"); cout << s.at (8); } catch (out_of_range & exc) { cerr << "exception out_of_range capturée; " << exc.what() << endl; } }// f() |
void f (void)
{ cout << "\nTest de l'exception length_error dans la classe vector\n\n"; try { vector <int> v; v.reserve (v.max_size() + 1); } catch (length_error & exc) { cerr << "exception length_error capturée; " << exc.what() << endl; } } // f() |
Cependant, à l'exécution, le programme indique le message "Segmentation fault", affiché avant que l'exception ait pu être levée (probablement au niveau de l'allocateur) : ce n'est donc pas dû au compilateur C++.
Remarque : selon la norme, et contrairement à la classe string, la fonction reserve() est la seule à pouvoir lever cette exception pour la classe vector. La fonction resize() par exemple n'est pas censée lever d'exception. La norme ajoute en note :
"reserve() uses Allocator::allocate() which may throw an appropriate exception."
© D. Mathieu
mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique