Is it possible to make a default-initialized class std::is_trivial for performance purposes












3















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










share|improve this question




















  • 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
















3















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










share|improve this question




















  • 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














3












3








3








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










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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














  • 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












1 Answer
1






active

oldest

votes


















3














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.






share|improve this answer


























  • 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











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
});


}
});














draft saved

draft discarded


















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









3














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.






share|improve this answer


























  • 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
















3














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.






share|improve this answer


























  • 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














3












3








3







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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



















  • 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




















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

Calculate evaluation metrics using cross_val_predict sklearn

Insert data from modal to MySQL (multiple modal on website)