mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-27 13:30:05 +00:00
[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
This commit is contained in:
parent
551152f7d8
commit
229aa6d23b
@ -295,6 +295,78 @@ ordering right::
|
|||||||
| OtherSpecialSquare
|
| OtherSpecialSquare
|
||||||
| Circle
|
| Circle
|
||||||
|
|
||||||
|
A Bug to be Aware Of
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
The example just given opens the door to bugs where the ``classof``\s are
|
||||||
|
not updated to match the ``Kind`` enum when adding (or removing) classes to
|
||||||
|
(from) the hierarchy.
|
||||||
|
|
||||||
|
Continuing the example above, suppose we add a ``SomewhatSpecialSquare`` as
|
||||||
|
a subclass of ``Square``, and update the ``ShapeKind`` enum like so:
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
enum ShapeKind {
|
||||||
|
SK_Square,
|
||||||
|
SK_SpecialSquare,
|
||||||
|
SK_OtherSpecialSquare,
|
||||||
|
+ SK_SomewhatSpecialSquare,
|
||||||
|
SK_Circle
|
||||||
|
}
|
||||||
|
|
||||||
|
Now, suppose that we forget to update ``Square::classof()``, so it still
|
||||||
|
looks like:
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
static bool classof(const Shape *S) {
|
||||||
|
// BUG: Returns false when S->getKind() == SK_SomewhatSpecialSquare,
|
||||||
|
// even though SomewhatSpecialSquare "is a" Square.
|
||||||
|
return S->getKind() >= SK_Square &&
|
||||||
|
S->getKind() <= SK_OtherSpecialSquare;
|
||||||
|
}
|
||||||
|
|
||||||
|
As the comment indicates, this code contains a bug. A straightforward and
|
||||||
|
non-clever way to avoid this is to introduce an explicit ``SK_LastSquare``
|
||||||
|
entry in the enum when adding the first subclass(es). For example, we could
|
||||||
|
rewrite the example at the beginning of `Concrete Bases and Deeper
|
||||||
|
Hierarchies`_ as:
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
enum ShapeKind {
|
||||||
|
SK_Square,
|
||||||
|
+ SK_SpecialSquare,
|
||||||
|
+ SK_OtherSpecialSquare,
|
||||||
|
+ SK_LastSquare,
|
||||||
|
SK_Circle
|
||||||
|
}
|
||||||
|
...
|
||||||
|
// Square::classof()
|
||||||
|
- static bool classof(const Shape *S) {
|
||||||
|
- return S->getKind() == SK_Square;
|
||||||
|
- }
|
||||||
|
+ static bool classof(const Shape *S) {
|
||||||
|
+ return S->getKind() >= SK_Square &&
|
||||||
|
+ S->getKind() <= SK_LastSquare;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
Then, adding new subclasses is easy:
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
enum ShapeKind {
|
||||||
|
SK_Square,
|
||||||
|
SK_SpecialSquare,
|
||||||
|
SK_OtherSpecialSquare,
|
||||||
|
+ SK_SomewhatSpecialSquare,
|
||||||
|
SK_LastSquare,
|
||||||
|
SK_Circle
|
||||||
|
}
|
||||||
|
|
||||||
|
Notice that ``Square::classof`` does not need to be changed.
|
||||||
|
|
||||||
.. _classof-contract:
|
.. _classof-contract:
|
||||||
|
|
||||||
The Contract of ``classof``
|
The Contract of ``classof``
|
||||||
|
Loading…
Reference in New Issue
Block a user