Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++ > Communauté
Communauté Suivez l'actualité C++ et contribuez à la vie de la communauté francophone C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Actualité déjà publiée
 
Outils de la discussion
Publicité
'
Vieux 03/06/2012, 16h56   #1
Klaim
Expert Confirmé
 
Avatar de Klaim
 
Homme Joel Lamotte
Développeur de jeux vidéo
Inscription : août 2004
Messages : 1 552
Détails du profil
Informations personnelles :
Nom : Homme Joel Lamotte
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 1 552
Points : 2 970
Points : 2 970
Par défaut Folly, la bibliothèque C++ de Facebook

Folly : la bibliothèque C++ open-source de Facebook
Une initiative pour partager les outils utilisés en interne

Herb Sutter, l'expert reconnu du langage C++, encense dans son dernier billet de blog l'initiative de Facebook qui vient tout juste de publier en open-source sa bibliothèque d'utilités : Folly.

Cette bibliothèque contient tout un tas d'algorithmes et de structures utilisés dans le code de Facebook. L'essentiel des fonctionnalités couvre les problèmes de performances ou d'absence d'implémentations trouvés dans les bibliothèques déjà existantes comme Boost ou la bibliothèque standard.

De plus en plus d'entreprises mettent leur code source à disposition de tous et permettent de compléter les fonctionnalités fournies par les bibliothèques C++ disponibles. Certaines ont pour but d'être intégrées dans la bibliothèque standard C++, dans le but de corriger ce qui semble être pour Herb Sutter le problème majeur du C++ : le manque d'outils disponibles de façon standard.

Dépôt GitHub de Folly : https://github.com/facebook/folly.

Et vous :
Que pensez-vous de cette initiative de Facebook ?
Pensez-vous pouvoir utiliser cette bibliothèque dans vos propres projets ?

Sources :
Klaim est actuellement connecté   Envoyer un message privé Réponse avec citation 80
Vieux 04/06/2012, 01h12   #2
Arzar
Membre Expert
 
Inscription : mai 2008
Messages : 937
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 937
Points : 1 783
Points : 1 783
Je viens de jeter en œil aux sources et il y a en effet beaucoup de choses intéressantes. Alors attention, il ne faut pas s'attendre à des bibliothèques de haut niveau genre XML, base de donnée ou réseau. Cela reste avant tout une collection de petits composants d'usage général. La majorité de ces composants sont en fait des structures de données orientées multithreading.

Extrait du readme de Folly :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#### `Arena.h`, `ThreadCachedArena.h`
Simple arena for memory allocation: multiple allocations get freed all
at once. With threaded version.
#### [`AtomicHashMap.h`, `AtomicHashArray.h`](AtomicHashMap.md)
High-performance atomic hash map with almost lock-free operation.
#### [`Benchmark.h`](Benchmark.md)
A small framework for benchmarking code. Client code registers
benchmarks, optionally with an argument that dictates the scale of the
benchmark (iterations, working set size etc). The framework runs
benchmarks (subject to a command-line flag) and produces formatted
output with timing information.
#### `Bits.h`
Various bit manipulation utilities optimized for speed.
#### `Bits.h`
Bit-twiddling functions that wrap the
[ffsl(l)](<a href="http://linux.die.net/man/3/ffsll" target="_blank">http://linux.die.net/man/3/ffsll</a>) primitives in a uniform
interface.
#### `ConcurrentSkipList.h`
An implementation of the structure described in [A Provably Correct
Scalable Concurrent Skip
List](<a href="http://www.cs.tau.ac.il/~shanir/nir-pubs-web/Papers/OPODIS2006-BA.pdf" target="_blank">http://www.cs.tau.ac.il/~shanir/nir-...DIS2006-BA.pdf</a>)
by Herlihy et al.
#### [`Conv.h`](Conv.md)
A variety of data conversion routines (notably to and from string),
optimized for speed and safety.
#### `DiscriminatedPtr.h`
Similar to `boost::variant`, but restricted to pointers only. Uses the
highest-order unused 16 bits in a pointer as discriminator. So
`sizeof(DiscriminatedPtr<int, string, Widget>) == sizeof(void*)`.
#### [`dynamic.h`](Dynamic.md)
Dynamically-typed object, created with JSON objects in mind.
#### `Endian.h`
Endian conversion primitives.
####`Escape.h`
Escapes a string in C style.
####`eventfd.h`
Wrapper around the
[`eventfd`](<a href="http://www.kernel.org/doc/man-pages/online/pages/man2/eventfd.2.html" target="_blank">http://www.kernel.org/doc/man-pages/...eventfd.2.html</a>)
system call.
####[`FBString.h`](FBString.md)
A drop-in implementation of `std::string` with a variety of optimizations.
####[`FBVector.h`](FBVector.md)
A mostly drop-in implementation of `std::vector` with a variety of
optimizations.
####`Foreach.h`
Pseudo-statements (implemented as macros) for iteration.
####[`Format.h`](Format.md)
Python-style formatting utilities.
####[`GroupVarint.h`](GroupVarint.md)
[Group Varint
encoding](<a href="http://www.ir.uwaterloo.ca/book/addenda-06-index-compression.html" target="_blank">http://www.ir.uwaterloo.ca/book/adde...mpression.html</a>)
for 32-bit values.
####`Hash.h`
Various popular hash function implementations.
####[`Histogram.h`](Histogram.md)
A simple class for collecting histogram data.
####`IntrusiveList.h`
Convenience type definitions for using `boost::intrusive_list`.
####`json.h`
JSON serializer and deserializer. Uses `dynamic.h`.
####`Likely.h`
Wrappers around [`__builtin_expect`](<a href="http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html" target="_blank">http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html</a>).
####`Malloc.h`
Memory allocation helpers, particularly when using jemalloc.
####`MapUtil.h`
Helpers for finding items in associative containers (such as
`std::map` and `std::unordered_map`).
####[`PackedSyncPtr.h`](PackedSyncPtr.md)
A highly specialized data structure consisting of a pointer, a 1-bit
spin lock, and a 15-bit integral, all inside one 64-bit word.
####`Preprocessor.h`
Necessarily evil stuff.
####`PrettyPrint.h`
Pretty-printer for numbers that appends suffixes of unit used: bytes
(kb, MB, ...), metric suffixes (k, M, G, ...), and time (s, ms, us,
ns, ...).
####[`ProducerConsumerQueue.h`](ProducerConsumerQueue.md)
Lock free single-reader, single-writer queue.
####`Random.h`
Defines only one function---`randomNumberSeed()`.
####`Range.h`
Boost-style range facility and the `StringPiece` specialization.
####`RWSpinLock.h`
Fast and compact reader-writer spin lock.
####`ScopeGuard.h`
C++11 incarnation of the old [ScopeGuard](<a href="http://drdobbs.com/184403758" target="_blank">http://drdobbs.com/184403758</a>) idiom.
####[`SmallLocks.h`](SmallLocks.md)
Very small spin locks (1 byte and 1 bit).
####`small_vector.h`
Vector with the small buffer optimization and an ptional embedded
`PicoSpinLock`.
####`sorted_vector_types.h`
Collections similar to `std::map` but implemented as sorted vectors.
####`StlAllocator.h`
STL allocator wrapping a simple allocate/deallocate interface.
####`String.h`
String utilities that connect `folly::fbstring` with `std::string`.
####[`Synchronized.h`](Synchronized.md)
High-level synchronization library.
####`System.h`
Demangling and errno utilities.
####[`ThreadCachedInt.h`](ThreadCachedInt.md)
High-performance atomic increment using thread caching.
####[`ThreadLocal.h`](ThreadLocal.md)
Improved thread local storage for non-trivial types.
####`TimeoutQueue.h`
Queue with per-item timeout.
####`Traits.h`
Type traits that complement those defined in the standard C++11 header
`<traits>`.
####`Unicode.h`
Defines the `codePointToUtf8` function.
Petite remarque, à la lecture du code j'ai été très étonné de voir que Folly propose du C++ résolument moderne.

Par comparaison, tous les autres gros projets open source (de ma connaissance) en C++ et suffisamment massifs pour avoir eux aussi ce genre de brique de base bien fournies (par exemple llvm/clang ou chromium) ont des contraintes fortes forçant une approche assez conservative, du genre :
- Pas d'exception
- C++03 uniquement, souvent en bannissant certains aspects du langage pour être accepté par le plus grand nombre de compilateurs.
- Pas de bibliothèque tierce.

Du coup c'est assez fascinant de voir que Folly, qui si je comprends bien est la brique de base sur laquelle s’appuie tout le reste du code C++ chez Facebook, au contraire :
- Utilise les exceptions.
- Utilise extensivement le C++11. Il faut d'ailleurs au minimum gcc 4.6 pour compiler le code, vu l'utilisation régulière de feature comme les variadic template ou rvalue reference.
- Utilise extensivement boost.
Arzar est actuellement connecté   Envoyer un message privé Réponse avec citation 50
Vieux 04/06/2012, 11h41   #3
Errata
Membre à l'essai
 
Homme
Étudiant
Inscription : octobre 2011
Messages : 5
Détails du profil
Informations personnelles :
Sexe : Homme

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : octobre 2011
Messages : 5
Points : 22
Points : 22
Citation:
Du coup c'est assez fascinant de voir que Folly, qui si je comprends bien est la brique de base sur laquelle s’appuie tout le reste du code C++ chez Facebook
Le code a la marque d'Andrei Alexandrescu, qui est le guru C++ chez facebook.
Un code de qualité, dont certain bout de code mériterais d’être envisager pour s’intégrer dans la lib standard (je pense au JSON serializer/deserializer, et aux container thread-safe, fonction de hash).
Errata est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2012, 11h53   #4
David_g
Membre expérimenté
 
Inscription : mai 2010
Messages : 209
Détails du profil
Informations forums :
Inscription : mai 2010
Messages : 209
Points : 599
Points : 599
Je me demande si HipHop peut utiliser aussi cette bibliothèque.
David_g est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2012, 12h44   #5
mitkl
Rédacteur
 
Avatar de mitkl
 
Homme Timothée Bernard
Étudiant
Inscription : février 2010
Messages : 370
Détails du profil
Informations personnelles :
Nom : Homme Timothée Bernard
Âge : 21
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : février 2010
Messages : 370
Points : 1 325
Points : 1 325
Citation:
Envoyé par David_g Voir le message
Je me demande si HipHop peut utiliser aussi cette bibliothèque.
Citation:
As engineers here, we use, contribute to, and release a lot of open source software, including pieces of our core infrastructure such as HipHop and Thrift.
__________________
Si vous ne savez toujours pas ce qu’est la récursivité, relisez cette phrase.

Mon blog sur la programmation et l'informatique !
mitkl est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 04/06/2012, 14h34   #6
Luc Hermitte
Expert Confirmé Sénior

 
Avatar de Luc Hermitte
 
Inscription : août 2003
Messages : 4 522
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : août 2003
Messages : 4 522
Points : 5 730
Points : 5 730
Vous êtes tombés sur des exemples d'utilisation des exceptions ? Car dans le README il est écrit que non.
__________________
FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média.
Luc Hermitte est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2012, 15h22   #7
Klaim
Expert Confirmé
 
Avatar de Klaim
 
Homme Joel Lamotte
Développeur de jeux vidéo
Inscription : août 2004
Messages : 1 552
Détails du profil
Informations personnelles :
Nom : Homme Joel Lamotte
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 1 552
Points : 2 970
Points : 2 970
J'allais le dire: dans le readme du dossier principal il est ecrit en gros qu'il est interdit d'utiliser les exceptions. Peut être que ca a changé et que ce n'est plus d'actuallité....ou alors yen a qui n'ont pas suivi les regles...
Klaim est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2012, 15h30   #8
alexrtz
Membre Expert
 
Avatar de alexrtz
 
Inscription : juin 2003
Messages : 622
Détails du profil
Informations personnelles :
Âge : 30

Informations forums :
Inscription : juin 2003
Messages : 622
Points : 1 092
Points : 1 092
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
folly/AtomicHashMap.h: *   Insert returns false if there is a key collision and throws if the max size
folly/AtomicHashMap.h:   *   AtomicHashMapFullError is thrown.
folly/ProducerConsumerQueue.h:      throw std::bad_alloc();
folly/json.h: * system, the serializer will throw.
folly/json.h:     * precisely represented by fit a double---instead, throws an
folly/dynamic-inl.h:   * double, or throws if either is not a numeric type.
folly/dynamic-inl.h:      throw TypeError("numeric", a.type(), b.type());
folly/dynamic-inl.h:inline bool dynamic::isString() const { return get_nothrow<fbstring>(); }
folly/dynamic-inl.h:inline bool dynamic::isObject() const { return get_nothrow<ObjectImpl>(); }
folly/dynamic-inl.h:inline bool dynamic::isBool()   const { return get_nothrow<bool>(); }
folly/dynamic-inl.h:inline bool dynamic::isArray()  const { return get_nothrow<Array>(); }
folly/dynamic-inl.h:inline bool dynamic::isDouble() const { return get_nothrow<double>(); }
folly/dynamic-inl.h:inline bool dynamic::isInt()    const { return get_nothrow<int64_t>(); }
folly/dynamic-inl.h:inline bool dynamic::isNull()   const { return get_nothrow<void*>(); }
folly/dynamic-inl.h:    throw TypeError("object", type_);
folly/dynamic-inl.h:      throw TypeError("int64", type(), o.type());           \
folly/dynamic-inl.h:    throw TypeError("object/array", type());
folly/dynamic-inl.h:    throw TypeError("object/array", type());
folly/dynamic-inl.h:  if (auto* parray = get_nothrow<Array>()) {
folly/dynamic-inl.h:      throw std::out_of_range("out of range in dynamic array");
folly/dynamic-inl.h:      throw TypeError("int64", idx.type());
folly/dynamic-inl.h:  auto* pobj = get_nothrow<ObjectImpl>();
folly/dynamic-inl.h:    throw std::out_of_range(to<std::string>(
folly/dynamic-inl.h:  if (auto* ar = get_nothrow<Array>()) {
folly/dynamic-inl.h:  if (auto* obj = get_nothrow<ObjectImpl>()) {
folly/dynamic-inl.h:  if (auto* str = get_nothrow<fbstring>()) {
folly/dynamic-inl.h:  throw TypeError("array/object", type());
folly/dynamic-inl.h:    throw TypeError("not null/object/array", type());
folly/dynamic-inl.h:  case INT64:    return to<T>(*get_nothrow<int64_t>());
folly/dynamic-inl.h:  case DOUBLE:   return to<T>(*get_nothrow<double>());
folly/dynamic-inl.h:  case BOOL:     return to<T>(*get_nothrow<bool>());
folly/dynamic-inl.h:  case STRING:   return to<T>(*get_nothrow<fbstring>());
folly/dynamic-inl.h:    throw TypeError("int/double/bool/string", type());
folly/dynamic-inl.h:T* dynamic::get_nothrow() {
folly/dynamic-inl.h:T const* dynamic::get_nothrow() const {
folly/dynamic-inl.h:  return const_cast<dynamic*>(this)->get_nothrow<T>();
folly/dynamic-inl.h:  if (auto* p = get_nothrow<T>()) {
folly/dynamic-inl.h:  throw TypeError(TypeInfo<T>::name, type());
folly/docs/Dynamic.md:`folly::TypeError`. Other exceptions can also be thrown if
folly/docs/Dynamic.md:    dynamic hugeDoub = hugeInt.asDouble();  // throws a folly/Conv.h error,
folly/docs/Conv.md:* Otherwise, `to` inserts bounds checks and throws
folly/docs/FBVector.md:assignment is the same as bitblitting the bits over) or a nothrow
folly/docs/FBVector.md:      (boost::has_trivial_assign<T>::value || boost::has_nothrow_constructor<T>::value));
folly/FormatArg.h:   * Validate the argument for the given type; throws on error.
folly/FormatArg.h:   * is thrown otherwise).
folly/FormatArg.h:   * integer (an exception is thrown otherwise).
folly/FormatArg.h:  throw std::invalid_argument(to<std::string>(
folly/Conv.h:  ((condition) ? (void)0 : throw std::range_error(                      \
folly/Conv.h: * in which case digits_to throws.
folly/Conv.h:    throw std::range_error("Cannot convert string " +
folly/Conv.h:      throw std::range_error("Unable to convert an empty string"
folly/Conv.h:  throw std::range_error("Unable to convert \"" + src->toString()
folly/Conv.h:    throw std::range_error(
folly/sorted_vector_types.h:  // Nothrow as long as swap() on the Compare type is nothrow.
folly/sorted_vector_types.h:  // Nothrow as long as swap() on the Compare type is nothrow.
folly/test/DiscriminatedPtrTest.cpp:  EXPECT_EQ(&a, p.get_nothrow<int>());
folly/test/DiscriminatedPtrTest.cpp:  EXPECT_EQ(&a, static_cast<const Ptr&>(p).get_nothrow<int>());
folly/test/DiscriminatedPtrTest.cpp:  EXPECT_EQ(static_cast<void*>(NULL), p.get_nothrow<void>());
folly/test/DiscriminatedPtrTest.cpp:  EXPECT_EQ(static_cast<int*>(NULL), p.get_nothrow<int>());
folly/test/ScopeGuardTest.cpp:      throw std::runtime_error("destructors should never throw!");
folly/test/ScopeGuardTest.cpp:  "destructors should never throw");
folly/test/ScopeGuardTest.cpp: * to close a db connection regardless if an exception was thrown during
folly/test/ScopeGuardTest.cpp: *     throw e; // re-throw the exception
folly/test/ScopeGuardTest.cpp:        throw std::runtime_error("throwing an expected error");
folly/test/ScopeGuardTest.cpp:        throw "never throw raw strings";
folly/test/ScopeGuardTest.cpp:    throw std::runtime_error("test");
folly/test/FBStringLibstdcxxStdexceptTest.cpp:          (use std::__throw_* from funcexcept.h instead)
folly/test/ConvTest.cpp:  // However, if the next character would cause an overflow it throws a
folly/test/ConvTest.cpp:    throw std::runtime_error("empty string");
folly/test/ConvTest.cpp:      throw std::runtime_error("overflow");
folly/test/ConvTest.cpp:    throw std::runtime_error("extra chars at the end");
folly/test/AtomicHashMapTest.cpp:    static bool throwException_ = false;
folly/test/AtomicHashMapTest.cpp:    throwException_ = !throwException_;
folly/test/AtomicHashMapTest.cpp:    if (throwException_) {
folly/test/AtomicHashMapTest.cpp:      throw 1;
folly/test/small_vector_test.cpp:int throwCounter = 1;
folly/test/small_vector_test.cpp:  if (!--throwCounter) {
folly/test/small_vector_test.cpp:    throw TestException();
folly/test/small_vector_test.cpp:// Check that throws don't break the basic guarantee for some cases.
folly/test/small_vector_test.cpp:// throwing code paths to occur.
folly/test/small_vector_test.cpp:    throwCounter = 1000;
folly/test/small_vector_test.cpp:    throwCounter = 1000;
folly/test/small_vector_test.cpp:      throwCounter = 1000;
folly/test/small_vector_test.cpp:      throwCounter = counter;
folly/test/small_vector_test.cpp:       * of the above push_back's, and one of the Throwers throws,
folly/test/small_vector_test.cpp:    throwCounter = 4;
folly/StlAllocator.h: * alignment required on your system), throwing std::bad_alloc if the
folly/StlAllocator.h: *     if (!p) throw std::bad_alloc();
folly/dynamic.h: * complete interface than the raw type), and it'll just throw a
folly/dynamic.h:   * those types.  For objects, we throw TypeError.
folly/dynamic.h:   * These throw TypeError when used with types or type combinations
folly/dynamic.h:   * These functions may also throw if you use 64-bit integers with
folly/dynamic.h:   * throws TypeError.
folly/dynamic.h:   * non-arrays will throw a TypeError.
folly/dynamic.h:   * value) in an object.  Calling these on non-objects will throw a TypeError.
folly/dynamic.h:   * the given name.  Otherwise throws TypeError.
folly/dynamic.h:   * will throw a TypeError.  Using an index that is out of range or
folly/dynamic.h:   * object-element that's not present throws std::out_of_range.
folly/dynamic.h:   * In the case of an array, the index must be an integer, and this will throw
folly/dynamic.h:   * value if the key isn't present.  The const overload will throw
folly/dynamic.h:   * Only defined for objects, throws TypeError otherwise.
folly/dynamic.h:   * Inserts the supplied key-value pair to an object, or throws if
folly/dynamic.h:   * Append elements to an array.  If this is not an array, throws
folly/dynamic.h:  template<class T> T*       get_nothrow();
folly/dynamic.h:  template<class T> T const* get_nothrow() const;
folly/String.h: * In strict mode (default), throws std::invalid_argument if it encounters
folly/String.h: * This function may allocate memory (and therefore throw).
folly/String.h:struct has_nothrow_constructor<folly::basic_fbstring<T> > : true_type {
folly/DiscriminatedPtr.h: * throws an exception (and get_nothrow returns nullptr)
folly/DiscriminatedPtr.h:  T* get_nothrow() noexcept {
folly/DiscriminatedPtr.h:  const T* get_nothrow() const noexcept {
folly/DiscriminatedPtr.h:   * Types), and throws std::invalid_argument if this DiscriminatedPtr is empty
folly/DiscriminatedPtr.h:      throw std::invalid_argument("Invalid type");
folly/DiscriminatedPtr.h:      throw std::invalid_argument("Invalid type");
folly/DiscriminatedPtr.h:    if (n == 0) throw std::invalid_argument("Empty DiscriminatedPtr");
folly/DiscriminatedPtr.h:    if (n == 0) throw std::invalid_argument("Empty DiscriminatedPtr");
folly/Format-inl.h:  // and throw if we see any lone "}"
folly/Format-inl.h:        throw std::invalid_argument(
folly/Format-inl.h:      throw std::invalid_argument(
folly/Format-inl.h:      throw std::invalid_argument("folly::format: missing ending '}'");
folly/Format-inl.h:      throw std::invalid_argument(
folly/String-inl.h:        throw std::invalid_argument("incomplete escape sequence");
folly/String-inl.h:          throw std::invalid_argument("incomplete hex escape sequence");
folly/String-inl.h:        throw std::invalid_argument("invalid escape sequence");
folly/small_vector.h: * overflow the in situ capacity we throw an exception.
folly/small_vector.h:      // threw: if someone throws from a move constructor the effects
folly/small_vector.h:      throw;
folly/small_vector.h:      throw;
folly/small_vector.h:   * anything throws, undo what we did.
folly/small_vector.h:      throw;
folly/small_vector.h:   * Basic guarantee only.  Provides the nothrow guarantee iff our
folly/small_vector.h:   * value_type has a nothrow move or copy constructor.
folly/small_vector.h:        throw;
folly/small_vector.h:      throw;
folly/small_vector.h:     * constructor throwing by clearing the whole vector).
folly/small_vector.h:     * constructor throws, you either need a nothrow default
folly/small_vector.h:     * constructor or a nothrow copy/move to get something back in the
folly/small_vector.h:      throw std::out_of_range();
folly/small_vector.h:      throw std::out_of_range();
folly/small_vector.h:   * objects and insertion outside the function, otherwise exception is thrown.
folly/small_vector.h:      throw std::length_error("max_size exceeded in small_vector");
folly/small_vector.h:      throw std::bad_alloc();
folly/small_vector.h:        throw;
folly/small_vector.h:        throw;
folly/small_vector.h:        throw;
folly/small_vector.h:        throw;
folly/small_vector.h:// Basic guarantee only, or provides the nothrow guarantee iff T has a
folly/small_vector.h:// nothrow move or copy constructor.
folly/experimental/TestUtil.cpp:    throw std::system_error(errno, std::system_category(),
folly/experimental/TestUtil.cpp:      throw std::system_error(errno, std::system_category(),
folly/experimental/io/Cursor.h:      throw std::out_of_range("underflow");
folly/experimental/io/Cursor.h:      throw std::out_of_range("underflow");
folly/experimental/io/Cursor.h:      throw std::out_of_range("overflow");
folly/experimental/io/Cursor.h: * (and push() and ensure() will throw) if growth == 0.
folly/experimental/io/Cursor.h:      throw std::out_of_range("can't grow buffer chain");
folly/experimental/io/IOBuf.h:   * second argument.  The free function must never throw exceptions.
folly/experimental/io/IOBuf.h:   * On error, std::bad_alloc will be thrown.  If freeOnError is true (the
folly/experimental/io/IOBuf.h:   * default) the buffer will be freed before throwing the error.
folly/experimental/io/IOBuf.h:   * On error, std::bad_alloc will be thrown.
folly/experimental/io/IOBuf.h:   * Currently unshare may also throw std::overflow_error if it tries to
folly/experimental/io/IOBuf.cpp:    throw std::bad_alloc();
folly/experimental/io/IOBuf.cpp:      throw std::bad_alloc();
folly/experimental/io/IOBuf.cpp:    throw;
folly/experimental/io/IOBuf.cpp:          // The user's free function is not allowed to throw.
folly/experimental/io/IOBuf.cpp:    throw;
folly/experimental/io/IOBuf.cpp:    throw std::overflow_error("IOBuf chain too large to coalesce");
folly/experimental/io/IOBuf.cpp:      // The user's free function should never throw.  Otherwise we might
folly/experimental/io/IOBuf.cpp:      // throw from the IOBuf destructor.  Other code paths like coalesce()
folly/experimental/io/IOBuf.cpp:      // also assume that decrementRefcount() cannot throw.
folly/experimental/io/IOBuf.cpp:            throw std::bad_alloc();
folly/experimental/io/IOBuf.cpp:          throw std::bad_alloc();
folly/experimental/io/IOBuf.cpp:      throw std::bad_alloc();
folly/experimental/io/IOBuf.cpp:    throw std::bad_alloc();
folly/experimental/io/IOBufQueue.h:   * @throws std::underflow_error if n exceeds the number of bytes
folly/experimental/io/IOBufQueue.h:      throw std::invalid_argument("IOBufQueue: chain length not cached");
folly/experimental/io/IOBufQueue.cpp:      throw std::underflow_error(
folly/experimental/io/IOBufQueue.cpp:      throw std::underflow_error(
folly/experimental/io/IOBufQueue.cpp:      throw std::underflow_error(
folly/Traits.h:  struct has_nothrow_constructor<  __VA_ARGS__ > : ::boost::true_type {};
folly/Traits.h: * above, and that it has a nothrow constructor. Most types can be
folly/Traits.h:struct has_nothrow_constructor< std::pair<T, U> >
folly/Traits.h:    : ::boost::mpl::and_< has_nothrow_constructor<T>,
folly/Traits.h:                          has_nothrow_constructor<U> > {};
folly/Range.h:    if (i >= size()) throw std::out_of_range("index out of range");
folly/Range.h:    if (i >= size()) throw std::out_of_range("index out of range");
folly/FBVector.h:  boost::has_nothrow_constructor<T>::value
folly/FBVector.h:  !boost::has_nothrow_constructor<T>::value
folly/FBVector.h: * value. If the operation throws, destroys all objects constructed so
folly/FBVector.h:  } else if (boost::has_nothrow_constructor<T>::value) {
folly/FBVector.h:      throw;
folly/FBVector.h: * operation throws, destroys all objects constructed so far and calls
folly/FBVector.h:      throw;
folly/FBVector.h:      // Careful here, fill and uninitialized_fill may throw. The
folly/FBVector.h:      throw std::out_of_range("fbvector: index is greater than size.");
folly/FBVector.h:        throw;
folly/FBVector.h:        throw;
folly/FBString.h:      void (*throw_exc)(const char*),
folly/FBString.h:    if (!condition) throw_exc(msg);
folly/FBString.h:          std::__throw_logic_error(err.c_str());
folly/FBString.h:    enforce(res_arg <= max_size(), std::__throw_length_error, "");
folly/FBString.h:    enforce(n <= size(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(n < size(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos <= sz, std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos <= sz, std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos2 <= str.length(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos <= length(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos <= length(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos <= length(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos <= size(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos2 <= str.length(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos <= size(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos <= size(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos <= size(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos1 <= size(), std::__throw_out_of_range, "");
folly/FBString.h:    enforce(pos2 <= str.size(), std::__throw_out_of_range, "");
folly/detail/ThreadLocalDetail.h:      throw std::runtime_error("pthread_key_create failed: " + msg);
folly/detail/ThreadLocalDetail.h:      LOG(WARNING) << "Destructor discarding an exception that was thrown.";
folly/detail/ThreadLocalDetail.h:          throw std::bad_alloc();
folly/AtomicHashMap-inl.h:    throw AtomicHashMapFullError();
folly/AtomicHashArray-inl.h:            throw;
folly/ScopeGuard.h: *   // this will throw an exception upon error, which
folly/ScopeGuard.h: *   // an exception was not thrown, so don't execute
folly/String.cpp:    throw std::runtime_error(
folly/String.cpp:      throw std::runtime_error(
folly/json.cpp:    throw std::runtime_error("folly::decodeUtf8 empty/invalid string");
folly/json.cpp:    throw std::runtime_error(
folly/json.cpp:      throw std::runtime_error(
folly/json.cpp:        throw std::runtime_error(
folly/json.cpp:          throw std::runtime_error(
folly/json.cpp:  throw std::runtime_error("folly::decodeUtf8 encoding length maxed out");
folly/json.cpp:      throw std::runtime_error("folly::toJson: JSON object key was not a "
folly/json.cpp:      throw ParseError(lineNum_, context(),
folly/json.cpp:    throw ParseError(lineNum_, context(), what);
folly/Arena.h: *      alignment required on your system; throw std::bad_alloc if the
folly/Arena.h:    if (!mem) throw std::bad_alloc();
__________________
"Je suis incapable d'expliquer ce qui se passa ensuite : je lâchai quelque chose, quelque chose à quoi je m'agrippais depuis toujours sans m'en rendre compte. Je m'enfonçais dans une obscurité chaude, moelleuse et protectrice, tandis qu'un loup montait la garde par mes propres yeux."
alexrtz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2012, 15h48   #9
Klaim
Expert Confirmé
 
Avatar de Klaim
 
Homme Joel Lamotte
Développeur de jeux vidéo
Inscription : août 2004
Messages : 1 552
Détails du profil
Informations personnelles :
Nom : Homme Joel Lamotte
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 1 552
Points : 2 970
Points : 2 970
Merci, je viens de rajouter l'info dans ma réponse là: http://programmers.stackexchange.com.../113481#113481
Klaim est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2012, 16h00   #10
Arzar
Membre Expert
 
Inscription : mai 2008
Messages : 937
Détails du profil
Informations forums :
Inscription : mai 2008
Messages : 937
Points : 1 783
Points : 1 783
Oui c'est vraiment curieux ce désaccord dans Folly entre doc et code.
Le code actuel utilise assez régulièrement les exceptions. On en trouve parfois jusque dans les briques vraiment basique comme fbvector et small_vector (std::out_of_range, std::length_error, std::bad_alloc etc.). Il y a aussi régulièrement des commentaires indiquant le degré d'exception safety de certaines fonctions. Autre exemple, la biliothèque json qui utilise systématiquement les exceptions pour remonter les erreurs de parsing (std::runtime_error(to<std::string>("json parse error on line ", line))

Klaim :
Pour ta réponse sur stackoverflow, un autre exemple célèbre de compagnie bannissant les exceptions en bloc pour la totalité de leur code C++ : google
http://google-styleguide.googlecode....xml#Exceptions
(intéressant car contient de nombreuses justifications)
Arzar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2012, 17h55   #11
Luc Hermitte
Expert Confirmé Sénior

 
Avatar de Luc Hermitte
 
Inscription : août 2003
Messages : 4 522
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : août 2003
Messages : 4 522
Points : 5 730
Points : 5 730
google est dans un des rares cas où c'est correctement justifié : base de vieux code trop importante pour initier une migration comme ça.
__________________
FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média.
Luc Hermitte est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/06/2012, 18h46   #12
JolyLoic
Rédacteur/Modérateur
 
Avatar de JolyLoic
 
Homme Loïc Joly
Développeur informatique
Inscription : août 2004
Messages : 4 675
Détails du profil
Informations personnelles :
Nom : Homme Loïc Joly
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 4 675
Points : 9 897
Points : 9 897
Posté sur la mailing list de boost :
Citation:
https://www.facebook.com/notes/faceb...50864656793920

I'm Tudor, one of the folly developers. I'll try to answer your questions
or poke the appropriate people

Re: "NO EXCEPTIONS" in the README -- the README file was intended for
internal Facebook contributors (hence stray references to internal paths),
and "NO EXCEPTIONS" referred to "no exceptions to the rules above", NOT "no
C++ exceptions". Will fix / clarify / remove soon.

-Tudor.
Donc les exceptions C++ sont autorisées !

Remarque @Klaim : Dans http://programmers.stackexchange.com.../113481#113481 je ne suis pas d'accord avec toute une série d'arguments qui vont tous dans le sens : De toute façon, une exception, c'est juste des infos de crash plus jolies, mais nous, on n'a pas le droit de crasher (et on a des environnements qui nous permettent de ne pas le faire). C'est typiquement l'argument contre une fonctionnalité de quelqu'un qui ne l'a pas utilisée pour de vrai. Une exception n'est pas un crash. C'est un mécanisme de remontées d'erreurs comme un autre, qui comme un autre peut conduire au traitement silencieux de celles-ci, ou à la fin du programme, ou à un tas d'intermédiaires, mais uniquement selon le code de gestion des erreurs, qui lui est indépendant de la technique de remontée utilisée.

Je ne nie pas l’argument performances (ni ne l'admets, je n'ai juste pas assez d'infos là dessus). Mais j'accepterais que les jeux n'ont aucun intérêt à utiliser un mécanisme d'exception le jour où on me justifiera que les jeux n'ont pas non plus de mécanisme de code de retour de fonction indiquant si la fonction s'est finie avec succès ou pas.
JolyLoic est déconnecté   Envoyer un message privé Réponse avec citation 40
Vieux 04/06/2012, 20h00   #13
Klaim
Expert Confirmé
 
Avatar de Klaim
 
Homme Joel Lamotte
Développeur de jeux vidéo
Inscription : août 2004
Messages : 1 552
Détails du profil
Informations personnelles :
Nom : Homme Joel Lamotte
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 1 552
Points : 2 970
Points : 2 970
Citation:
Envoyé par JolyLoic Voir le message
Posté sur la mailing list de boost :

Donc les exceptions C++ sont autorisées !
Ah, devancé

Citation:

Remarque @Klaim : Dans http://programmers.stackexchange.com.../113481#113481 je ne suis pas d'accord avec toute une série d'arguments qui vont tous dans le sens : De toute façon, une exception, c'est juste des infos de crash plus jolies, mais nous, on n'a pas le droit de crasher (et on a des environnements qui nous permettent de ne pas le faire). C'est typiquement l'argument contre une fonctionnalité de quelqu'un qui ne l'a pas utilisée pour de vrai. Une exception n'est pas un crash. C'est un mécanisme de remontées d'erreurs comme un autre, qui comme un autre peut conduire au traitement silencieux de celles-ci, ou à la fin du programme, ou à un tas d'intermédiaires, mais uniquement selon le code de gestion des erreurs, qui lui est indépendant de la technique de remontée utilisée.

Je ne nie pas l’argument performances (ni ne l'admets, je n'ai juste pas assez d'infos là dessus). Mais j'accepterais que les jeux n'ont aucun intérêt à utiliser un mécanisme d'exception le jour où on me justifiera que les jeux n'ont pas non plus de mécanisme de code de retour de fonction indiquant si la fonction s'est finie avec succès ou pas.

Et je suis tout a fait d'accord! (voir les commentaires a ce sujet). Personellement, jusqu'a ce que j'ai des contraintes fortes, je prefere de loin avoir les exceptions activées quand je bosse sur des jeux. Parfois je n'ai pas le choix, mais heureusement ça deviens (pour moi) de plus en plus rare.

Comme je le dis dans ma réponse, ce sont les arguments apportés, pas les miens mais ceux qui sont constamment ressassés.
Le problème de performance est toutefois important une fois qu'on fait un blockbuster bien gourmand mais sinon il n'a pas lieu d'être un probleme.
Klaim est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2012, 11h39   #14
Ekleog
Membre émérite
 
Homme Léo Gaspard
Étudiant
Inscription : janvier 2012
Messages : 433
Détails du profil
Informations personnelles :
Nom : Homme Léo Gaspard
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2012
Messages : 433
Points : 875
Points : 875
Sauf que, comme le fait remarquer un des articles qui est en traduction (je crois), les exceptions sont souvent moins gourmandes en ressources que l'utilisation d'un code de retour. En tout cas, tant qu'elles restent exceptionnelles, bien sûr. Mais, si il y a autant d'erreurs que de retours normaux, est-ce toujours une erreur ?
Ekleog est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/06/2012, 12h48   #15
Freem
Expert Confirmé
 
Homme
Développeur informatique
Inscription : décembre 2008
Messages : 777
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : décembre 2008
Messages : 777
Points : 2 812
Points : 2 812
La consommation en ressources du traitement des exceptions varie selon le compilateur, donc il est difficile d'affirmer de façon catégorique que ça pèse vraiment lourd.
Et, naturellement, j'ai ici parlé de ressources de façon générale.
Selon mes lectures en survol à ce sujet, il y a grosso modo deux stratégies pour les gérer:
_ augmenter la taille du code
_ augmenter les traitements processeur

Avec GCC, selon la doc, une exception n'a un coût que si elle est lancée, mais le binaire augmente un peu.
Honnêtement... J'aime beaucoup l'optimisation, mais je préfère un programme qui ne crash pas, et qui ne contiens pas de memory leak.
Donc, j'aime bien les contrôles d'erreur.
Si on veut me dire que les exceptions consomment, je veux voir un comparatif, entre un source C et un C++, ou chaque fonction du C retourne un code erreur, et ou celui-ci est systématiquement vérifié.
Ca inclut printf/scanf, naturellement...

Si il s'avère que le binaire C résultant d'un tel code est plus rapide, plus petit en RAM, plus petit sur le disque, et plus lisible, alors je serai conquis. (En fait, même juste la moitié de ces arguments commencerait à me faire réfléchir... mais bon, je doute qu'un code sans exception vérifie toutes les conditions d'erreurs. Déjà qu'avec les exceptions ce n'est pas toujours le cas...)

Sauf que:
_ coller des if partout dans le code augmente la taille du binaire, même si ce ne sont que 3 octets par occurrence pour un short jump (selon mes souvenirs d'asm)
_ coller des if partout dans le code implique des vérifications. Et chaque vérification consomme du temps processeur. J'imagine une fonction récursive qui à été appelée 50 fois... et j'ai un sérieux doute quand à la légèreté des vérifs de retour d'erreur classique.
_ "accessoirement" mélanger le code de traitement d'erreur avec le code d'exécution normal, ça rend le code illisible.

Bon, après, c'est vrai aussi, il semble qu'il est possible de bricoler un système pas trop mal en C avec signal.h et les longjump, mais je n'en ai pas encore vu, moi.
Je pense que les exceptions, c'est un peu comme l'orienté objet: quelque chose dont tout le monde parle mais qui est moins répandu qu'on ne voudrait le croire.
En tout cas, je n'en ai pas vu à mon taf actuel, ni sur les 2-3 projets open source que j'ai osé vouloir lire. (Ni l'un ni l'autre d'ailleurs: ni exceptions, ni conception orientée objet, alors que les langages le permettent...)
Freem est déconnecté   Envoyer un message privé Réponse avec citation 40
Vieux 06/06/2012, 13h30   #16
Ekleog
Membre émérite
 
Homme Léo Gaspard
Étudiant
Inscription : janvier 2012
Messages : 433
Détails du profil
Informations personnelles :
Nom : Homme Léo Gaspard
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2012
Messages : 433
Points : 875
Points : 875
Citation:
Envoyé par Freem Voir le message
La consommation en ressources du traitement des exceptions varie selon le compilateur, donc il est difficile d'affirmer de façon catégorique que ça pèse vraiment lourd.
Et, naturellement, j'ai ici parlé de ressources de façon générale.
Selon mes lectures en survol à ce sujet, il y a grosso modo deux stratégies pour les gérer:
_ augmenter la taille du code
_ augmenter les traitements processeur
Augmenter la taille du code => Oui mais non.
Soit il y a setjmp / longjmp ; qui génèrent des points de saut pour gérer les exceptions. Méthode qui n'est quasiment plus utilisée, car elle n'est efficace que dans le cas d'une exception très fréquente. Mais, il me semble qu'il y a des options pour la réactiver sur certains compilateurs.
Soit il y a la exception handling table (pas sûr du nom). En gros, lorsqu'on lance une exception, on va voir la table et on en tire les choses à faire. Ca alourdit un peu l'exécutable, mais ... Par rapport à tous les opcodes de jz +X ret (voire plus d'opcodes encode), je ne suis pas certain que ça augmente la taille du code par rapport à un code de gestion d'erreurs manuelle.

Citation:
Envoyé par Freem
Avec GCC, selon la doc, une exception n'a un coût que si elle est lancée, mais le binaire augmente un peu.
Honnêtement... J'aime beaucoup l'optimisation, mais je préfère un programme qui ne crash pas, et qui ne contiens pas de memory leak.
Donc, j'aime bien les contrôles d'erreur.
=> ?
Là, je ne comprense pas.
C'est de l'humour, peut-être ?
Parce que, au moins, avec une exception on crash proprement (destructeurs, etc.).
Avec un code de contrôle d'erreur de retour dans lequel on oublie ne serait-ce qu'une erreur possible (après tout, il suffit d'oublier un if, c'est tellement fréquent), on va d'abord tout exploser en continuant l'exécution d'un code dont les préconditions ne sont pas respectées, et ensuite on va crasher. Avec donc un risque de corruption du reste du système (fs, sauvegarde,...) beaucoup plus grand.

Citation:
Envoyé par Freem
Si on veut me dire que les exceptions consomment, je veux voir un comparatif, entre un source C et un C++, ou chaque fonction du C retourne un code erreur, et ou celui-ci est systématiquement vérifié.
Ca inclut printf/scanf, naturellement...

Si il s'avère que le binaire C résultant d'un tel code est plus rapide, plus petit en RAM, plus petit sur le disque, et plus lisible, alors je serai conquis. (En fait, même juste la moitié de ces arguments commencerait à me faire réfléchir... mais bon, je doute qu'un code sans exception vérifie toutes les conditions d'erreurs. Déjà qu'avec les exceptions ce n'est pas toujours le cas...)
Comment oublier de gérer une exception ?
Dans tous les cas, le binaire sera plus lent (plus de sauts conditionnels), à peu près aussi grand en RAM (opcodes supplémentaires vs. table d'exceptions), aussi grand sur le disque (idem), et moins lisible (nécessité de vérifier le code de retour même avec du SBRM) ...

Citation:
Envoyé par Freem
Sauf que:
_ coller des if partout dans le code augmente la taille du binaire, même si ce ne sont que 3 octets par occurrence pour un short jump (selon mes souvenirs d'asm)
_ coller des if partout dans le code implique des vérifications. Et chaque vérification consomme du temps processeur. J'imagine une fonction récursive qui à été appelée 50 fois... et j'ai un sérieux doute quand à la légèreté des vérifs de retour d'erreur classique.
_ "accessoirement" mélanger le code de traitement d'erreur avec le code d'exécution normal, ça rend le code illisible.

Bon, après, c'est vrai aussi, il semble qu'il est possible de bricoler un système pas trop mal en C avec signal.h et les longjump, mais je n'en ai pas encore vu, moi.
Je pense que les exceptions, c'est un peu comme l'orienté objet: quelque chose dont tout le monde parle mais qui est moins répandu qu'on ne voudrait le croire.
En tout cas, je n'en ai pas vu à mon taf actuel, ni sur les 2-3 projets open source que j'ai osé vouloir lire. (Ni l'un ni l'autre d'ailleurs: ni exceptions, ni conception orientée objet, alors que les langages le permettent...)
En bref, un énorme +1.
Ekleog est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 06/06/2012, 14h49   #17
Klaim
Expert Confirmé
 
Avatar de Klaim
 
Homme Joel Lamotte
Développeur de jeux vidéo
Inscription : août 2004
Messages : 1 552
Détails du profil
Informations personnelles :
Nom : Homme Joel Lamotte
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 1 552
Points : 2 970
Points : 2 970
Ce que beaucoup oublient avec l'argument des ifs a la place des exceptions, c'est que le choix de ne pas utiliser d'exceptions n'implique pas que l'on va checker les erreurs. C'est ce qui se passe dans beaucoup de jeux vidéos: on met beaucoup beaucoup d'assertions pour crasher le plus vite possible pendant le développement ou au moins logger et puis continuer, mais une fois que le jeu est suffisamment prêt on vire tout et il n'y a aucune vérification d'erreur. Une des raisons qui rends cela possible est tout simplement qu'un jeu console n'a que des inputs fixes et prévisibles, du coup il est possible de se retrouver, après beaucoup de travail, avec un jeu qui
tourne "parfaitement" sans aucune vérification du tout.

Cela étant dis, hors du contexte d'un jeu console, pour une console des anciennes générations du moins, cet argument ne tiens plus.

Pour le point sur l'activation des exceptions: en théorie on est censé ne pas payer si il n'y a aucun throw de fait. Dans la pratique on paye mémé dans ce cas. Par contre, aujourd’hui sur la plupart des plateformes (mais pas sur console ou sur la plupart des systèmes embarques, pas les smartphones) le cout est très faible donc ça va encore. Sur certaines consoles comme la DS le simple fait qu'il n'y ai que 4mo de mémoire virtuelle "normale" a laquelle on doit imputer la taille de l’exécutable fais que le coût du mécanisme d'exception en terme de taille d’exécutable n'est pas du tout acceptable. Je ne sais pas pour la 3ds qui a sacrement beaucoup plus de mémoire, mais j’imagine qu'il y a des contraintes similaires parce que c'est pas non plus un pc ou même un smartphone.
Klaim est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/06/2012, 16h50   #18
Luc Hermitte
Expert Confirmé Sénior

 
Avatar de Luc Hermitte
 
Inscription : août 2003
Messages : 4 522
Détails du profil
Informations personnelles :
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : août 2003
Messages : 4 522
Points : 5 730
Points : 5 730
Ouais enfin. Il y a erreur alors.
Si le code peut utiliser des assert plutôt que des if dans tous les sens, cela signifie que les éventuelles erreurs trouvées sont des erreurs de programmation et non de problèmes dans le contexte de l'exécution (comme une connexion réseau à internet perdue).

Les exceptions n'ont pas leur place. Pas plus que les if. C'est des assertions qu'il faut, et le débat exception ou pas n'a pas lieu d'être pour ces "erreurs là".
__________________
FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média.
Luc Hermitte est déconnecté   Envoyer un message privé Réponse avec citation 40
Vieux 06/06/2012, 18h31   #19
Klaim
Expert Confirmé
 
Avatar de Klaim
 
Homme Joel Lamotte
Développeur de jeux vidéo
Inscription : août 2004
Messages : 1 552
Détails du profil
Informations personnelles :
Nom : Homme Joel Lamotte
Localisation : France

Informations professionnelles :
Activité : Développeur de jeux vidéo
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2004
Messages : 1 552
Points : 2 970
Points : 2 970
Oui mais la encore il y a subtilité.

Quel est l'effet d'une assertion? Log + crash souvent.

Mais pour un jeu ça peut etre problématique. Une série d'assertions peuvent donner plus d'indices sur l'ampleur d'un probleme qu'une seule assertion qui fait tout crasher.

Du coup beaucoup d'assertions sont implémentées pour logger et etre evaluable optionellement, pour quand meme generer du code dans le cas ou l'assertion ne passe pas OU pour crasher OU pour lancer une exception.
En plus les assertions sont rarement gardées dans le code d'un jeu, ils sont utilisés seulement dans des versions "debug" ou "release debug" du jeu, pour des soucis de performances.

Du coup exceptions, tests unitaires et assertions devraient marcher mains dans la mains, mais devraient être desactivable si besoin.

Enfin bref, ce que je veux dire c'est que comprendre l'ampleur et du sujet mais aussi comprendre que les termes employés ont tendance à englober trop de choses qui ne sont pas forcément sous entendues par toutes les parties de la discussion, fait que les discussions tournent rapidement steriles sur le sujet...
Klaim est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2012, 19h53   #20
Ekleog
Membre émérite
 
Homme Léo Gaspard
Étudiant
Inscription : janvier 2012
Messages : 433
Détails du profil
Informations personnelles :
Nom : Homme Léo Gaspard
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2012
Messages : 433
Points : 875
Points : 875
Citation:
Envoyé par Klaim Voir le message
Ce que beaucoup oublient avec l'argument des ifs a la place des exceptions, c'est que le choix de ne pas utiliser d'exceptions n'implique pas que l'on va checker les erreurs. C'est ce qui se passe dans beaucoup de jeux vidéos: on met beaucoup beaucoup d'assertions pour crasher le plus vite possible pendant le développement ou au moins logger et puis continuer, mais une fois que le jeu est suffisamment prêt on vire tout et il n'y a aucune vérification d'erreur. Une des raisons qui rends cela possible est tout simplement qu'un jeu console n'a que des inputs fixes et prévisibles, du coup il est possible de se retrouver, après beaucoup de travail, avec un jeu qui
tourne "parfaitement" sans aucune vérification du tout.
Auquel cas, un équivalent exceptions qui permet de conserver la remontée de pile automatique (bien sûr, si on ne cherche de travail que pour les assertions ça ne servira à rien, mais bon...) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define THROW(...) throw __VA_ARGS__
#define TRY(...) try { __VA_ARGS__ }
#define CATCH_EXPAND(...) __VA_ARGS__
#define CATCH(T, ...) catch(CATCH_EXPAND T) { __VA_ARGS__ }
// Bien sûr, en release, on supprime tous les rhs
 
// Usage :
TRY (
  // Code normal, comme si try { }
  THROW(some::exception<a, b, c>(abc));
  // etc.
) CATCH ((some::exception<a, b, c> const & e),
  // Code de gestion d'erreur)
)
Après, j'avoue en voir mal l'intérêt.

Citation:
Cela étant dis, hors du contexte d'un jeu console, pour une console des anciennes générations du moins, cet argument ne tiens plus.

Pour le point sur l'activation des exceptions: en théorie on est censé ne pas payer si il n'y a aucun throw de fait. Dans la pratique on paye mémé dans ce cas. Par contre, aujourd’hui sur la plupart des plateformes (mais pas sur console ou sur la plupart des systèmes embarques, pas les smartphones) le cout est très faible donc ça va encore. Sur certaines consoles comme la DS le simple fait qu'il n'y ai que 4mo de mémoire virtuelle "normale" a laquelle on doit imputer la taille de l’exécutable fais que le coût du mécanisme d'exception en terme de taille d’exécutable n'est pas du tout acceptable. Je ne sais pas pour la 3ds qui a sacrement beaucoup plus de mémoire, mais j’imagine qu'il y a des contraintes similaires parce que c'est pas non plus un pc ou même un smartphone.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
 
#define C 0x42424242
 
int f(int i) {
   if (i == C + 1) {
#ifdef WITH_EXC
      throw "some exception";
#else
      return 0x42;
#endif
   }
   return i - C;
}
 
int main() {
   int i;
   std::cin >> i;
   i += C;
#ifdef WITH_EXC
   try {
      return f(i);
   } catch(...) {
      return 1;
   }
#else
   return f(i);
#endif
}
Compilé avec WITH_EXC, g++ triche : il inline. Mais on peut décemment supposer que les fonctions méritant des exceptions ne seront, théoriquement, pas inlinées.

Sans WITH_EXC :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
(gdb) disas main
Dump of assembler code for function main:
   0x0000000000400810 <+0>:     sub    rsp,0x18
   0x0000000000400814 <+4>:     mov    edi,0x600e60
   0x0000000000400819 <+9>:     lea    rsi,[rsp+0xc]
   0x000000000040081e <+14>:    call   0x4007c0 <_ZNSirsERi@plt>
   0x0000000000400823 <+19>:    mov    edi,DWORD PTR [rsp+0xc]
   0x0000000000400827 <+23>:    add    edi,0x42424242
   0x000000000040082d <+29>:    mov    DWORD PTR [rsp+0xc],edi
   0x0000000000400831 <+33>:    call   0x400980 <_Z1fi>
   0x0000000000400836 <+38>:    add    rsp,0x18
   0x000000000040083a <+42>:    ret    
   0x000000000040083b <+43>:    mov    rdi,rax
   0x000000000040083e <+46>:    call   0x4007f0 <__cxa_begin_catch@plt>
   0x0000000000400843 <+51>:    call   0x4007e0 <__cxa_end_catch@plt>
   0x0000000000400848 <+56>:    mov    eax,0x1
   0x000000000040084d <+61>:    jmp    0x400836 <main+38>
End of assembler dump.
(gdb) disas f
Dump of assembler code for function _Z1fi:
   0x0000000000400980 <+0>:     cmp    edi,0x42424243
   0x0000000000400986 <+6>:     je     0x40098f <_Z1fi+15>
   0x0000000000400988 <+8>:     lea    eax,[rdi-0x42424242]
   0x000000000040098e <+14>:    ret    
   0x000000000040098f <+15>:    push   rax
   0x0000000000400990 <+16>:    mov    edi,0x8
   0x0000000000400995 <+21>:    call   0x4007b0 <__cxa_allocate_exception@plt>
   0x000000000040099a <+26>:    xor    edx,edx
   0x000000000040099c <+28>:    mov    QWORD PTR [rax],0x400a54
   0x00000000004009a3 <+35>:    mov    esi,0x600f80
   0x00000000004009a8 <+40>:    mov    rdi,rax
   0x00000000004009ab <+43>:    call   0x4007d0 <__cxa_throw@plt>
End of assembler dump.
En suivant le déroulement de main, je ne vois nulle part ne fût-ce que la plus infime trace de code dédié à l'exception sur le chemin du code normal (réserver pile, lire entier, ajouter constante, appeler f, retourner).
En suivant celui de f, je ne vois que le strict nécessaire : un unique saut conditionel, contrairement à un test de retour où il faudrait tester à chaque appel de fonction.

Où est donc le coût des exceptions ? (A part dans le poids mémoire du runtime __cxa_*, qui sera probablement de toute façon inclus, sauf peut-être si -fno-exceptions est passé.)
Ekleog est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Actualité déjà publiée
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 19h19.


 
 
 
 
Partenaires

Hébergement Web