Is it possible to make a default-initialized class std::is_trivial for performance purposes
When making simple pod-classes, it seems I have to make a choice between safety and performance. This happens as a result of that std::is_trivial
, which is used in STL to determine if a class can be copied via memmove
/memcpy
, or resort to a loop.
The following snippet demonstrates the difference:
// A can be copied via memmove
struct A { int x; }; // x is left uninitialized
static_assert(std::is_trivial_v<A>);
static_assert(std::is_trivially_copyable_v<A>);
auto copy_a(A* first, A* last, A* dst) { std::copy(first, last, dst); }
// B is prevented to be copied via memmove
struct B { int x{}; }; // x is initialized
static_assert(!std::is_trivial_v<B>);
static_assert(std::is_trivially_copyable_v<B>); // true
auto copy_b(B* first, B* last, B* dst) { std::copy(first, last, dst); }
From my perspective, it seems to be that std::copy would do fine to just utilize std::is_trivially_copyable<>
rather than std::is_trivial
, but I suppose there are subtle reasons std::copy uses std::is_trivial.
However, is there any way to make a class default initialized, but still allow STL to optimize the copying?
Notes:
- GodBolt available at https://godbolt.org/z/6tejQj
- Resorting to manual use of std::memcpy is not an option
c++ templates stl c++17
add a comment |
When making simple pod-classes, it seems I have to make a choice between safety and performance. This happens as a result of that std::is_trivial
, which is used in STL to determine if a class can be copied via memmove
/memcpy
, or resort to a loop.
The following snippet demonstrates the difference:
// A can be copied via memmove
struct A { int x; }; // x is left uninitialized
static_assert(std::is_trivial_v<A>);
static_assert(std::is_trivially_copyable_v<A>);
auto copy_a(A* first, A* last, A* dst) { std::copy(first, last, dst); }
// B is prevented to be copied via memmove
struct B { int x{}; }; // x is initialized
static_assert(!std::is_trivial_v<B>);
static_assert(std::is_trivially_copyable_v<B>); // true
auto copy_b(B* first, B* last, B* dst) { std::copy(first, last, dst); }
From my perspective, it seems to be that std::copy would do fine to just utilize std::is_trivially_copyable<>
rather than std::is_trivial
, but I suppose there are subtle reasons std::copy uses std::is_trivial.
However, is there any way to make a class default initialized, but still allow STL to optimize the copying?
Notes:
- GodBolt available at https://godbolt.org/z/6tejQj
- Resorting to manual use of std::memcpy is not an option
c++ templates stl c++17
5
is_trivially_copyable
should be sufficient. This is fixed in GCC trunk.
– T.C.
Nov 28 '18 at 9:02
Thanks! It seems though clang still uses std::is_trivial :/
– Viktor Sehr
Nov 28 '18 at 9:44
add a comment |
When making simple pod-classes, it seems I have to make a choice between safety and performance. This happens as a result of that std::is_trivial
, which is used in STL to determine if a class can be copied via memmove
/memcpy
, or resort to a loop.
The following snippet demonstrates the difference:
// A can be copied via memmove
struct A { int x; }; // x is left uninitialized
static_assert(std::is_trivial_v<A>);
static_assert(std::is_trivially_copyable_v<A>);
auto copy_a(A* first, A* last, A* dst) { std::copy(first, last, dst); }
// B is prevented to be copied via memmove
struct B { int x{}; }; // x is initialized
static_assert(!std::is_trivial_v<B>);
static_assert(std::is_trivially_copyable_v<B>); // true
auto copy_b(B* first, B* last, B* dst) { std::copy(first, last, dst); }
From my perspective, it seems to be that std::copy would do fine to just utilize std::is_trivially_copyable<>
rather than std::is_trivial
, but I suppose there are subtle reasons std::copy uses std::is_trivial.
However, is there any way to make a class default initialized, but still allow STL to optimize the copying?
Notes:
- GodBolt available at https://godbolt.org/z/6tejQj
- Resorting to manual use of std::memcpy is not an option
c++ templates stl c++17
When making simple pod-classes, it seems I have to make a choice between safety and performance. This happens as a result of that std::is_trivial
, which is used in STL to determine if a class can be copied via memmove
/memcpy
, or resort to a loop.
The following snippet demonstrates the difference:
// A can be copied via memmove
struct A { int x; }; // x is left uninitialized
static_assert(std::is_trivial_v<A>);
static_assert(std::is_trivially_copyable_v<A>);
auto copy_a(A* first, A* last, A* dst) { std::copy(first, last, dst); }
// B is prevented to be copied via memmove
struct B { int x{}; }; // x is initialized
static_assert(!std::is_trivial_v<B>);
static_assert(std::is_trivially_copyable_v<B>); // true
auto copy_b(B* first, B* last, B* dst) { std::copy(first, last, dst); }
From my perspective, it seems to be that std::copy would do fine to just utilize std::is_trivially_copyable<>
rather than std::is_trivial
, but I suppose there are subtle reasons std::copy uses std::is_trivial.
However, is there any way to make a class default initialized, but still allow STL to optimize the copying?
Notes:
- GodBolt available at https://godbolt.org/z/6tejQj
- Resorting to manual use of std::memcpy is not an option
c++ templates stl c++17
c++ templates stl c++17
edited Nov 28 '18 at 9:02
T.C.
107k14220329
107k14220329
asked Nov 28 '18 at 8:26
Viktor SehrViktor Sehr
8,61024060
8,61024060
5
is_trivially_copyable
should be sufficient. This is fixed in GCC trunk.
– T.C.
Nov 28 '18 at 9:02
Thanks! It seems though clang still uses std::is_trivial :/
– Viktor Sehr
Nov 28 '18 at 9:44
add a comment |
5
is_trivially_copyable
should be sufficient. This is fixed in GCC trunk.
– T.C.
Nov 28 '18 at 9:02
Thanks! It seems though clang still uses std::is_trivial :/
– Viktor Sehr
Nov 28 '18 at 9:44
5
5
is_trivially_copyable
should be sufficient. This is fixed in GCC trunk.– T.C.
Nov 28 '18 at 9:02
is_trivially_copyable
should be sufficient. This is fixed in GCC trunk.– T.C.
Nov 28 '18 at 9:02
Thanks! It seems though clang still uses std::is_trivial :/
– Viktor Sehr
Nov 28 '18 at 9:44
Thanks! It seems though clang still uses std::is_trivial :/
– Viktor Sehr
Nov 28 '18 at 9:44
add a comment |
1 Answer
1
active
oldest
votes
This should not be necessary in your circumstance. TriviallyCopyable is sufficient to be able to memcpy an object, and it does not require trivially default constructible. This seems to be simply an over-zealous C++ implementation.
That's what I thought too, but it seems both gcc 8.2 and clang latest (as of compiler explorer) are over-zealous :/ (But as mentioned, gcc has relaxed it's constrictions in trunk)
– Viktor Sehr
Nov 28 '18 at 15:18
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53515062%2fis-it-possible-to-make-a-default-initialized-class-stdis-trivial-for-performan%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This should not be necessary in your circumstance. TriviallyCopyable is sufficient to be able to memcpy an object, and it does not require trivially default constructible. This seems to be simply an over-zealous C++ implementation.
That's what I thought too, but it seems both gcc 8.2 and clang latest (as of compiler explorer) are over-zealous :/ (But as mentioned, gcc has relaxed it's constrictions in trunk)
– Viktor Sehr
Nov 28 '18 at 15:18
add a comment |
This should not be necessary in your circumstance. TriviallyCopyable is sufficient to be able to memcpy an object, and it does not require trivially default constructible. This seems to be simply an over-zealous C++ implementation.
That's what I thought too, but it seems both gcc 8.2 and clang latest (as of compiler explorer) are over-zealous :/ (But as mentioned, gcc has relaxed it's constrictions in trunk)
– Viktor Sehr
Nov 28 '18 at 15:18
add a comment |
This should not be necessary in your circumstance. TriviallyCopyable is sufficient to be able to memcpy an object, and it does not require trivially default constructible. This seems to be simply an over-zealous C++ implementation.
This should not be necessary in your circumstance. TriviallyCopyable is sufficient to be able to memcpy an object, and it does not require trivially default constructible. This seems to be simply an over-zealous C++ implementation.
edited Nov 28 '18 at 15:28
answered Nov 28 '18 at 15:06
Nicol BolasNicol Bolas
290k34481655
290k34481655
That's what I thought too, but it seems both gcc 8.2 and clang latest (as of compiler explorer) are over-zealous :/ (But as mentioned, gcc has relaxed it's constrictions in trunk)
– Viktor Sehr
Nov 28 '18 at 15:18
add a comment |
That's what I thought too, but it seems both gcc 8.2 and clang latest (as of compiler explorer) are over-zealous :/ (But as mentioned, gcc has relaxed it's constrictions in trunk)
– Viktor Sehr
Nov 28 '18 at 15:18
That's what I thought too, but it seems both gcc 8.2 and clang latest (as of compiler explorer) are over-zealous :/ (But as mentioned, gcc has relaxed it's constrictions in trunk)
– Viktor Sehr
Nov 28 '18 at 15:18
That's what I thought too, but it seems both gcc 8.2 and clang latest (as of compiler explorer) are over-zealous :/ (But as mentioned, gcc has relaxed it's constrictions in trunk)
– Viktor Sehr
Nov 28 '18 at 15:18
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53515062%2fis-it-possible-to-make-a-default-initialized-class-stdis-trivial-for-performan%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
5
is_trivially_copyable
should be sufficient. This is fixed in GCC trunk.– T.C.
Nov 28 '18 at 9:02
Thanks! It seems though clang still uses std::is_trivial :/
– Viktor Sehr
Nov 28 '18 at 9:44