mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
Address items called out in Issue 1424 (#1539)
* Address items called out in Issue 1424 * Fix issues caught by CI * Updates based on PR review
This commit is contained in:
parent
fc32070096
commit
39b9ebdf86
|
@ -4512,6 +4512,7 @@ Other default operations rules:
|
|||
* [C.86: Make `==` symmetric with respect of operand types and `noexcept`](#Rc-eq)
|
||||
* [C.87: Beware of `==` on base classes](#Rc-eq-base)
|
||||
* [C.89: Make a `hash` `noexcept`](#Rc-hash)
|
||||
* [C.90: Rely on constructors and assignment operators, not memset and memcpy](#Rc-memset)
|
||||
|
||||
## <a name="SS-defop"></a>C.defop: Default Operations
|
||||
|
||||
|
@ -6539,6 +6540,37 @@ That tends to work better than "cleverness" for non-specialists.
|
|||
|
||||
* Flag throwing `hash`es.
|
||||
|
||||
### <a name="Rc-memset"></a>C.90: Rely on constructors and assignment operators, not `memset` and `memcpy`
|
||||
|
||||
##### Reason
|
||||
|
||||
The standard C++ mechanism to construct an instance of a type is to call its constructor. As specified in guideline [C.41](#Rc-complete): a constructor should create a fully initialized object. No additional initialization, such as by `memcpy`, should be required.
|
||||
A type will provide a copy constructor and/or copy assignment operator to appropriately make a copy of the class, preserving the type's invariants. Using memcpy to copy a non-trivially copyable type has undefined behavior. Frequently this results in slicing, or data corruption.
|
||||
|
||||
##### Example, bad
|
||||
|
||||
struct base
|
||||
{
|
||||
virtual void update() = 0;
|
||||
std::shared_ptr<int> sp;
|
||||
};
|
||||
|
||||
struct derived : public base
|
||||
{
|
||||
void update() override {}
|
||||
};
|
||||
|
||||
void init(derived& a)
|
||||
{
|
||||
memset(&a, 0, sizeof(derived));
|
||||
}
|
||||
|
||||
void copy(derived& a, derived& b)
|
||||
{
|
||||
memcpy(&a, &b, sizeof(derived));
|
||||
}
|
||||
|
||||
|
||||
## <a name="SS-containers"></a>C.con: Containers and other resource handles
|
||||
|
||||
A container is an object holding a sequence of objects of some type; `std::vector` is the archetypical container.
|
||||
|
@ -18904,7 +18936,7 @@ Doing so takes away an `#include`r's ability to effectively disambiguate and to
|
|||
##### Note
|
||||
|
||||
An exception is `using namespace std::literals;`. This is necessary to use string literals
|
||||
in header files and given [the rules](http://eel.is/c++draft/over.literal) - users are required
|
||||
in header files and given [the rules](http://eel.is/c++draft/over.literal) - users are required
|
||||
to name their own UDLs `operator""_x` - they will not collide with the standard library.
|
||||
|
||||
##### Enforcement
|
||||
|
@ -20087,12 +20119,12 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
|
|||
my = y;
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
|
||||
~Picture()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
|
||||
bool Init()
|
||||
{
|
||||
// invariant checks
|
||||
|
@ -20105,14 +20137,14 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
|
|||
data = (char*) malloc(mx*my*sizeof(int));
|
||||
return data != nullptr;
|
||||
}
|
||||
|
||||
|
||||
void Cleanup()
|
||||
{
|
||||
if (data) free(data);
|
||||
data = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Picture picture(100, 0); // not ready-to-use picture here
|
||||
// this will fail..
|
||||
if (!picture.Init()) {
|
||||
|
@ -20127,14 +20159,14 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
|
|||
size_t mx;
|
||||
size_t my;
|
||||
vector<char> data;
|
||||
|
||||
|
||||
static size_t check_size(size_t s)
|
||||
{
|
||||
// invariant check
|
||||
Expects(s > 0);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
// even more better would be a class for a 2D Size as one single parameter
|
||||
Picture(size_t x, size_t y)
|
||||
|
@ -20147,10 +20179,10 @@ and errors (when we didn't deal correctly with semi-constructed objects consiste
|
|||
}
|
||||
// compiler generated dtor does the job. (also see C.21)
|
||||
};
|
||||
|
||||
|
||||
Picture picture1(100, 100);
|
||||
// picture is ready-to-use here...
|
||||
|
||||
|
||||
// not a valid size for y,
|
||||
// default contract violation behavior will call std::terminate then
|
||||
Picture picture2(100, 0);
|
||||
|
|
|
@ -301,6 +301,7 @@ md
|
|||
memberinit
|
||||
members'
|
||||
memcmp
|
||||
memcpy
|
||||
memmove
|
||||
memoization
|
||||
memoized
|
||||
|
|
Loading…
Reference in New Issue
Block a user