llvm.org GIT mirror llvm / 229aa6d
[docs] Discuss a potential bug to be aware of. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177224 91177308-0d34-0410-b5e6-96231b3b80d8 Sean Silva 6 years ago
1 changed file(s) with 72 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
294294 | OtherSpecialSquare
295295 | Circle
296296
297 A Bug to be Aware Of
298 --------------------
299
300 The example just given opens the door to bugs where the ``classof``\s are
301 not updated to match the ``Kind`` enum when adding (or removing) classes to
302 (from) the hierarchy.
303
304 Continuing the example above, suppose we add a ``SomewhatSpecialSquare`` as
305 a subclass of ``Square``, and update the ``ShapeKind`` enum like so:
306
307 .. code-block:: c++
308
309 enum ShapeKind {
310 SK_Square,
311 SK_SpecialSquare,
312 SK_OtherSpecialSquare,
313 + SK_SomewhatSpecialSquare,
314 SK_Circle
315 }
316
317 Now, suppose that we forget to update ``Square::classof()``, so it still
318 looks like:
319
320 .. code-block:: c++
321
322 static bool classof(const Shape *S) {
323 // BUG: Returns false when S->getKind() == SK_SomewhatSpecialSquare,
324 // even though SomewhatSpecialSquare "is a" Square.
325 return S->getKind() >= SK_Square &&
326 S->getKind() <= SK_OtherSpecialSquare;
327 }
328
329 As the comment indicates, this code contains a bug. A straightforward and
330 non-clever way to avoid this is to introduce an explicit ``SK_LastSquare``
331 entry in the enum when adding the first subclass(es). For example, we could
332 rewrite the example at the beginning of `Concrete Bases and Deeper
333 Hierarchies`_ as:
334
335 .. code-block:: c++
336
337 enum ShapeKind {
338 SK_Square,
339 + SK_SpecialSquare,
340 + SK_OtherSpecialSquare,
341 + SK_LastSquare,
342 SK_Circle
343 }
344 ...
345 // Square::classof()
346 - static bool classof(const Shape *S) {
347 - return S->getKind() == SK_Square;
348 - }
349 + static bool classof(const Shape *S) {
350 + return S->getKind() >= SK_Square &&
351 + S->getKind() <= SK_LastSquare;
352 + }
353
354 Then, adding new subclasses is easy:
355
356 .. code-block:: c++
357
358 enum ShapeKind {
359 SK_Square,
360 SK_SpecialSquare,
361 SK_OtherSpecialSquare,
362 + SK_SomewhatSpecialSquare,
363 SK_LastSquare,
364 SK_Circle
365 }
366
367 Notice that ``Square::classof`` does not need to be changed.
368
297369 .. _classof-contract:
298370
299371 The Contract of ``classof``