From f1b348e0db2c49b9980f732b8a4aeb5a719eb9a6 Mon Sep 17 00:00:00 2001 From: Zachary Henkel Date: Tue, 9 May 2017 16:17:45 -0700 Subject: [PATCH 1/9] Additional guidance around casts: - Warn on unnecessary casts - Avoid casts on arithmetic types - Add specializations of the rules for Pro-type-reinterpretcast --- CppCoreGuidelines.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index c42ffe3..3f0e83e 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -11235,6 +11235,7 @@ If you feel the need for a lot of casts, there may be a fundamental design probl * Force the elimination of C-style casts * Warn against named casts * Warn if there are many functional style casts (there is an obvious problem in quantifying 'many'). +* Warn against unnecessary casts. ### ES.49: If you must use a cast, use a named cast @@ -11287,7 +11288,8 @@ for example.) ##### Enforcement -Flag C-style and functional casts. +* Flag C-style and functional casts. +* Suggest brace initialization or gsl::narrow_cast instead of named casts on arithmetic types. ### ES.50: Don't cast away `const` @@ -18570,7 +18572,9 @@ Use of these casts can violate type safety and cause the program to access a var ##### Enforcement -Issue a diagnostic for any use of `reinterpret_cast`. To fix: Consider using a `variant` instead. +* Issue a diagnostic for any use of `reinterpret_cast`. To fix: Consider using a `variant` instead. +* Issue a separate diagnostic for any reinterpret_cast to void*. To fix: Remove the cast and allow the implicit type conversion. +* Issue a separate diagnostic for any reinterpret_cast from void*. To fix: Use static_cast instead ### Type.2: Don't use `static_cast` downcasts. Use `dynamic_cast` instead. From 6a7552db2117b375099832dafb59ff35ff46c82a Mon Sep 17 00:00:00 2001 From: Zachary Henkel Date: Wed, 24 May 2017 15:00:07 -0500 Subject: [PATCH 2/9] Additonal merge from https://github.com/isocpp/CppCoreGuidelines --- scripts/hunspell/isocpp.dic | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/scripts/hunspell/isocpp.dic b/scripts/hunspell/isocpp.dic index 4e472b4..6d0b901 100644 --- a/scripts/hunspell/isocpp.dic +++ b/scripts/hunspell/isocpp.dic @@ -1,4 +1,5 @@ ' +10'000 0xFF0000 0b0101'0101 10x @@ -78,6 +79,7 @@ class' clib Cline99 ClosePort +cm3 CommonMark composability composable @@ -126,6 +128,7 @@ default0 default00 defop del +deref derived1 derived2 destructors @@ -144,6 +147,7 @@ endl enum Enum enums +EoP eq eqdefault EqualityComparable @@ -183,6 +187,7 @@ g1 g2 GCC Geosoft +getline getx GFM Girou @@ -204,7 +209,9 @@ hnd homebrew HPL href +HTTP Hyslop +i2 IDE IDEs IEC @@ -262,6 +269,7 @@ lvalue lvalues m1 m2 +m3 macros2 malloc mallocfree @@ -300,6 +308,7 @@ mtx Murray93 mutex mutexes +mx myMap MyMap myset @@ -327,6 +336,7 @@ nonvirtual nonvirtually nothrow NR +nullness nullptr NVI ok @@ -478,6 +488,7 @@ stmt str strdup strlen +Str15 Stroustrup Stroustrup00 Stroustrup05 @@ -513,6 +524,7 @@ thread2 Tjark tmp TMP +tock TODO toolchains TotallyOrdered @@ -525,6 +537,8 @@ typeid typename typesafe UB +u1 +u2 unaliased uncompromised underuse From 2cd9993ae4c42e2e761768e9978529c56087e94a Mon Sep 17 00:00:00 2001 From: Zachary Henkel Date: Wed, 24 May 2017 15:31:11 -0500 Subject: [PATCH 3/9] Revise cast guidance following upstream edits --- CppCoreGuidelines.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 2943a40..94f20bb 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -11602,7 +11602,8 @@ Surprised? I'm just glad I didn't crash the program. ##### Note -Programmer who write casts typically assumes that they know what they are doing. +Programmers who write casts typically assume that they know what they are doing, +or that writing a cast makes the program "easier to read". In fact, they often disable the general rules for using values. Overload resolution and template instantiation usually pick the right function if there is a right function to pick. If there is not, maybe there ought to be, rather than applying a local fix (cast). @@ -11623,16 +11624,14 @@ Casts are widely (mis) used. Modern C++ has constructs that eliminate the need f * Use templates * Use `std::variant` - +* Rely on the well defined, safe, implicit conversions between pointer types ##### Enforcement * Force the elimination of C-style casts -* Warn against named casts -* Warn against unnecessary casts. * Warn if there are many functional style casts (there is an obvious problem in quantifying 'many'). * The [type profile](#Pro-type-reinterpretcast) bans `reinterpret_cast`. - +* Warn against [unnecessary pointer casts](#Pro-type-unnecessarycast). ### ES.49: If you must use a cast, use a named cast @@ -11694,6 +11693,7 @@ for example.) * Flag C-style and functional casts. * The [type profile](#Pro-type-reinterpretcast) bans `reinterpret_cast`. +* The [type profile](#Pro-type-arithmeticcast) warns when using `static_cast` between arithmetic types. ### ES.50: Don't cast away `const` @@ -19399,8 +19399,10 @@ An implementation of this profile shall recognize the following patterns in sour Type safety profile summary: -* Type.1: Don't use `reinterpret_cast`: -A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). +* Type.1: [Avoid casts](#Res-casts): + * Don't use `reinterpret_cast`; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). + * Don't a `static_cast` for arithmetic types; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). + * Don't use pointer unnecessary pointer casts; A strict version of [Avoid casts](#Res-casts) * Type.2: Don't use `static_cast` to downcast: [Use `dynamic_cast` instead](#Rh-dynamic_cast). * Type.3: Don't use `const_cast` to cast away `const` (i.e., at all): From ca359848138be134a750bf749acb9b7a59a031a5 Mon Sep 17 00:00:00 2001 From: Zachary Henkel Date: Wed, 31 May 2017 09:50:10 -0500 Subject: [PATCH 4/9] Try to make the linter happy --- CppCoreGuidelines.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 94f20bb..0b90fd5 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19400,9 +19400,11 @@ An implementation of this profile shall recognize the following patterns in sour Type safety profile summary: * Type.1: [Avoid casts](#Res-casts): + * Don't use `reinterpret_cast`; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). * Don't a `static_cast` for arithmetic types; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). * Don't use pointer unnecessary pointer casts; A strict version of [Avoid casts](#Res-casts) + * Type.2: Don't use `static_cast` to downcast: [Use `dynamic_cast` instead](#Rh-dynamic_cast). * Type.3: Don't use `const_cast` to cast away `const` (i.e., at all): From abd71982dace68c2bd1a63d6b843b7ad58517fe5 Mon Sep 17 00:00:00 2001 From: Zachary Henkel Date: Wed, 31 May 2017 10:03:02 -0500 Subject: [PATCH 5/9] Another try with the linter --- CppCoreGuidelines.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 0b90fd5..5ecbe42 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19399,12 +19399,10 @@ An implementation of this profile shall recognize the following patterns in sour Type safety profile summary: -* Type.1: [Avoid casts](#Res-casts): - - * Don't use `reinterpret_cast`; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). - * Don't a `static_cast` for arithmetic types; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). - * Don't use pointer unnecessary pointer casts; A strict version of [Avoid casts](#Res-casts) - +* Type.1: [Avoid casts](#Res-casts): +a.Don't use `reinterpret_cast`; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). +b.Don't a `static_cast` for arithmetic types; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). +c.Don't use pointer unnecessary pointer casts; A strict version of [Avoid casts](#Res-casts) * Type.2: Don't use `static_cast` to downcast: [Use `dynamic_cast` instead](#Rh-dynamic_cast). * Type.3: Don't use `const_cast` to cast away `const` (i.e., at all): From 2ef544d4ad64ad726b922155d9824ae3673864e8 Mon Sep 17 00:00:00 2001 From: Zachary Henkel Date: Wed, 31 May 2017 10:10:00 -0500 Subject: [PATCH 6/9] Additional formatting --- CppCoreGuidelines.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 5ecbe42..2e5236e 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19399,10 +19399,10 @@ An implementation of this profile shall recognize the following patterns in sour Type safety profile summary: -* Type.1: [Avoid casts](#Res-casts): -a.Don't use `reinterpret_cast`; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). -b.Don't a `static_cast` for arithmetic types; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). -c.Don't use pointer unnecessary pointer casts; A strict version of [Avoid casts](#Res-casts) +* Type.1: [Avoid casts](#Res-casts): +a.Don't use `reinterpret_cast`; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). +b.Don't a `static_cast` for arithmetic types; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). +c.Don't use pointer unnecessary pointer casts; A strict version of [Avoid casts](#Res-casts) * Type.2: Don't use `static_cast` to downcast: [Use `dynamic_cast` instead](#Rh-dynamic_cast). * Type.3: Don't use `const_cast` to cast away `const` (i.e., at all): From 3c867e5079ef15cdc44bd3245b6c23923390ad0c Mon Sep 17 00:00:00 2001 From: Zachary Henkel Date: Wed, 31 May 2017 10:11:19 -0500 Subject: [PATCH 7/9] Final style changes --- CppCoreGuidelines.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 2e5236e..a02012b 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19400,9 +19400,9 @@ An implementation of this profile shall recognize the following patterns in sour Type safety profile summary: * Type.1: [Avoid casts](#Res-casts): -a.Don't use `reinterpret_cast`; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). -b.Don't a `static_cast` for arithmetic types; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). -c.Don't use pointer unnecessary pointer casts; A strict version of [Avoid casts](#Res-casts) +a. Don't use `reinterpret_cast`; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). +b. Don't a `static_cast` for arithmetic types; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). +c. Don't use pointer unnecessary pointer casts; A strict version of [Avoid casts](#Res-casts) * Type.2: Don't use `static_cast` to downcast: [Use `dynamic_cast` instead](#Rh-dynamic_cast). * Type.3: Don't use `const_cast` to cast away `const` (i.e., at all): From 4b3352b4359f3f74caf4452d0cf7c13c4531e015 Mon Sep 17 00:00:00 2001 From: Zachary Henkel Date: Wed, 31 May 2017 10:24:39 -0500 Subject: [PATCH 8/9] Add words used in anchors to custom dictionary --- scripts/hunspell/isocpp.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/hunspell/isocpp.dic b/scripts/hunspell/isocpp.dic index 6d0b901..a1a79eb 100644 --- a/scripts/hunspell/isocpp.dic +++ b/scripts/hunspell/isocpp.dic @@ -42,6 +42,7 @@ archetypical arg argh args +arithmeticcast arr2 arrayindex ASIC @@ -550,6 +551,7 @@ uniqueptrparam unittest unittests unnamed2 +unnecessarycast use1 users' UTF From f3ff5bae6ddcd8ebb683eb6af25c75bf9a681462 Mon Sep 17 00:00:00 2001 From: Zachary Henkel Date: Fri, 2 Jun 2017 09:24:29 -0500 Subject: [PATCH 9/9] Clarify "unnecessary cast" by decomposing the class into identity casts and implicit casts. --- CppCoreGuidelines.md | 12 +++++++----- scripts/hunspell/isocpp.dic | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index a02012b..9c83944 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -11620,7 +11620,7 @@ If you feel the need for a lot of casts, there may be a fundamental design probl ##### Alternatives -Casts are widely (mis) used. Modern C++ has constructs that eliminate the need for casts in many contexts, such as +Casts are widely (mis) used. Modern C++ has rules and constructs that eliminate the need for casts in many contexts, such as * Use templates * Use `std::variant` @@ -11629,9 +11629,10 @@ Casts are widely (mis) used. Modern C++ has constructs that eliminate the need f ##### Enforcement * Force the elimination of C-style casts -* Warn if there are many functional style casts (there is an obvious problem in quantifying 'many'). +* Warn if there are many functional style casts (there is an obvious problem in quantifying 'many') * The [type profile](#Pro-type-reinterpretcast) bans `reinterpret_cast`. -* Warn against [unnecessary pointer casts](#Pro-type-unnecessarycast). +* Warn against [identity casts](#Pro-type-identitycast) between pointer types, where the source and target types are the same (#Pro-type-identitycast) +* Warn if a pointer cast could be [implicit](#Pro-type-implicitpointercast) ### ES.49: If you must use a cast, use a named cast @@ -19401,8 +19402,9 @@ Type safety profile summary: * Type.1: [Avoid casts](#Res-casts): a. Don't use `reinterpret_cast`; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). -b. Don't a `static_cast` for arithmetic types; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). -c. Don't use pointer unnecessary pointer casts; A strict version of [Avoid casts](#Res-casts) +b. Don't use `static_cast` for arithmetic types; A strict version of [Avoid casts](#Res-casts) and [prefer named casts](#Res-casts-named). +c. Don't cast between pointer types where the source type and the target type are the same; A strict version of [Avoid casts](#Res-casts). +d. Don't cast between pointer types when the conversion could be implicit; A strict version of [Avoid casts](#Res-casts). * Type.2: Don't use `static_cast` to downcast: [Use `dynamic_cast` instead](#Rh-dynamic_cast). * Type.3: Don't use `const_cast` to cast away `const` (i.e., at all): diff --git a/scripts/hunspell/isocpp.dic b/scripts/hunspell/isocpp.dic index a1a79eb..f74b369 100644 --- a/scripts/hunspell/isocpp.dic +++ b/scripts/hunspell/isocpp.dic @@ -214,6 +214,7 @@ HTTP Hyslop i2 IDE +identitycast IDEs IEC ifdef @@ -221,6 +222,7 @@ iff ifstream impactful Impl +implicitpointercast incompleat increment1 Incrementable @@ -551,7 +553,6 @@ uniqueptrparam unittest unittests unnamed2 -unnecessarycast use1 users' UTF