Slicing std::out_of_range to std::exception in Visual Studio vs g++ Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) Data science time! April 2019 and salary with experience Should we burninate the [wrap] tag? The Ask Question Wizard is Live!Exception slicing - is this due to generated copy constructor?What is object slicing?How to convert a std::string to const char* or char*?std::wstring VS std::stringWhy is “using namespace std” considered bad practice?What is “stdafx.h” used for in Visual Studio?Why does outputting a class with a conversion operator not work for std::string?std::atomic_is_lock_free(shared_ptr<T>*) didn't compileDifferences in size of std::string_view of non-null terminated char arrayC++ Exception not caught by base class

Denied boarding although I have proper visa and documentation. To whom should I make a complaint?

What exactly is a "Meth" in Altered Carbon?

How do I stop a creek from eroding my steep embankment?

Single word antonym of "flightless"

Is it true that "carbohydrates are of no use for the basal metabolic need"?

Should I discuss the type of campaign with my players?

Fundamental Solution of the Pell Equation

Can a non-EU citizen traveling with me come with me through the EU passport line?

Extract all GPU name, model and GPU ram

Can an alien society believe that their star system is the universe?

How to find out what spells would be useless to a blind NPC spellcaster?

Understanding Ceva's Theorem

Identify plant with long narrow paired leaves and reddish stems

What is the logic behind the Maharil's explanation of why we don't say שעשה ניסים on Pesach?

Why do we bend a book to keep it straight?

How discoverable are IPv6 addresses and AAAA names by potential attackers?

Why was the term "discrete" used in discrete logarithm?

How do pianists reach extremely loud dynamics?

Error "illegal generic type for instanceof" when using local classes

Why is "Consequences inflicted." not a sentence?

How much time will it take to get my passport back if I am applying for multiple Schengen visa countries?

How to answer "Have you ever been terminated?"

Storing hydrofluoric acid before the invention of plastics

Apollo command module space walk?



Slicing std::out_of_range to std::exception in Visual Studio vs g++



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
Data science time! April 2019 and salary with experience
Should we burninate the [wrap] tag?
The Ask Question Wizard is Live!Exception slicing - is this due to generated copy constructor?What is object slicing?How to convert a std::string to const char* or char*?std::wstring VS std::stringWhy is “using namespace std” considered bad practice?What is “stdafx.h” used for in Visual Studio?Why does outputting a class with a conversion operator not work for std::string?std::atomic_is_lock_free(shared_ptr<T>*) didn't compileDifferences in size of std::string_view of non-null terminated char arrayC++ Exception not caught by base class



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








2















I noticed the following behavior by accident (missed catching by reference), but I couldn't find information that, if I knew it before hand, would have allowed me to predict it.



With the minimal example



#include <iostream>
#include <stdexcept>


int main()

try

// Added this and the next line to check that the exception
// created has already the what() set to the input string.
std::out_of_range d("Out of range exception");
std::cout << "d.what() = " << d.what() << std::endl;
throw d;

catch (std::exception e) // Captured by value

std::cout << e.what() << std::endl;





If I compile it with g++ -std=c++17 and with Visual C++ I get different behaviors. With the first it prints d.what() = Out of range exceptionnstd::exception, while the second it prints d.what() = Out of range exceptionnOut of range exception.



In principle there could be slicing when the std::out_of_range is captured by value and converted to the std::exception type. This means that I could expect not getting the same behavior as an object from std::out_of_range object when printing its what().



Question: The part that I don't know how to explain is getting different behaviors for the two compilers. Is this because this slicing is undefined behavior in the C++ standarization, or is it that one of these two compilers is not complying with it?



Extra observation: I just noticed that in this link there is no mention of the class std::exception having a constructor that inputs a const char* const &, while in the Microsoft website they include it. My accidental example shows that they indeed implemented these classes differently. My question is still whether they were allowed (if this behavior is undefined) or if one of them is not complying and which one.










share|improve this question



















  • 1





    The issue isn't the slicing, IMO. It is when and where the what() is set. Is it set after the slicing occurs or before the slicing occurs? That is probably what should be investigated.

    – PaulMcKenzie
    Mar 8 at 17:48











  • @PaulMcKenzie As far as I understand (which is limited) and object of type std::out_of_range is created in the line with the throw. (One of)The constructor(s) of this class inputs the string to be the value of output by what(). Then during the catch this object is assigned to e, which is of type std::exception, a parent class of `std::out_of_range. Doesn't this mean that the slicing happens after? Let me do some experiments anyway.

    – user647486
    Mar 8 at 18:41











  • Try this answer

    – PaulMcKenzie
    Mar 8 at 18:44











  • @PaulMcKenzie I did a small change to the example. I created the std::out_of_range with its what() string, printed it before throwing. The message printed is the one passed to its constructor. However, after catching the slicing changed the message, when compiling with g++. With VisualC++ it prints the same message both times.

    – user647486
    Mar 8 at 18:47






  • 1





    @zett42 In the question it is said why: By accident. But well, a happy accident because it let me to learn something I had not seen.

    – user647486
    Mar 8 at 19:24


















2















I noticed the following behavior by accident (missed catching by reference), but I couldn't find information that, if I knew it before hand, would have allowed me to predict it.



With the minimal example



#include <iostream>
#include <stdexcept>


int main()

try

// Added this and the next line to check that the exception
// created has already the what() set to the input string.
std::out_of_range d("Out of range exception");
std::cout << "d.what() = " << d.what() << std::endl;
throw d;

catch (std::exception e) // Captured by value

std::cout << e.what() << std::endl;





If I compile it with g++ -std=c++17 and with Visual C++ I get different behaviors. With the first it prints d.what() = Out of range exceptionnstd::exception, while the second it prints d.what() = Out of range exceptionnOut of range exception.



In principle there could be slicing when the std::out_of_range is captured by value and converted to the std::exception type. This means that I could expect not getting the same behavior as an object from std::out_of_range object when printing its what().



Question: The part that I don't know how to explain is getting different behaviors for the two compilers. Is this because this slicing is undefined behavior in the C++ standarization, or is it that one of these two compilers is not complying with it?



Extra observation: I just noticed that in this link there is no mention of the class std::exception having a constructor that inputs a const char* const &, while in the Microsoft website they include it. My accidental example shows that they indeed implemented these classes differently. My question is still whether they were allowed (if this behavior is undefined) or if one of them is not complying and which one.










share|improve this question



















  • 1





    The issue isn't the slicing, IMO. It is when and where the what() is set. Is it set after the slicing occurs or before the slicing occurs? That is probably what should be investigated.

    – PaulMcKenzie
    Mar 8 at 17:48











  • @PaulMcKenzie As far as I understand (which is limited) and object of type std::out_of_range is created in the line with the throw. (One of)The constructor(s) of this class inputs the string to be the value of output by what(). Then during the catch this object is assigned to e, which is of type std::exception, a parent class of `std::out_of_range. Doesn't this mean that the slicing happens after? Let me do some experiments anyway.

    – user647486
    Mar 8 at 18:41











  • Try this answer

    – PaulMcKenzie
    Mar 8 at 18:44











  • @PaulMcKenzie I did a small change to the example. I created the std::out_of_range with its what() string, printed it before throwing. The message printed is the one passed to its constructor. However, after catching the slicing changed the message, when compiling with g++. With VisualC++ it prints the same message both times.

    – user647486
    Mar 8 at 18:47






  • 1





    @zett42 In the question it is said why: By accident. But well, a happy accident because it let me to learn something I had not seen.

    – user647486
    Mar 8 at 19:24














2












2








2








I noticed the following behavior by accident (missed catching by reference), but I couldn't find information that, if I knew it before hand, would have allowed me to predict it.



With the minimal example



#include <iostream>
#include <stdexcept>


int main()

try

// Added this and the next line to check that the exception
// created has already the what() set to the input string.
std::out_of_range d("Out of range exception");
std::cout << "d.what() = " << d.what() << std::endl;
throw d;

catch (std::exception e) // Captured by value

std::cout << e.what() << std::endl;





If I compile it with g++ -std=c++17 and with Visual C++ I get different behaviors. With the first it prints d.what() = Out of range exceptionnstd::exception, while the second it prints d.what() = Out of range exceptionnOut of range exception.



In principle there could be slicing when the std::out_of_range is captured by value and converted to the std::exception type. This means that I could expect not getting the same behavior as an object from std::out_of_range object when printing its what().



Question: The part that I don't know how to explain is getting different behaviors for the two compilers. Is this because this slicing is undefined behavior in the C++ standarization, or is it that one of these two compilers is not complying with it?



Extra observation: I just noticed that in this link there is no mention of the class std::exception having a constructor that inputs a const char* const &, while in the Microsoft website they include it. My accidental example shows that they indeed implemented these classes differently. My question is still whether they were allowed (if this behavior is undefined) or if one of them is not complying and which one.










share|improve this question
















I noticed the following behavior by accident (missed catching by reference), but I couldn't find information that, if I knew it before hand, would have allowed me to predict it.



With the minimal example



#include <iostream>
#include <stdexcept>


int main()

try

// Added this and the next line to check that the exception
// created has already the what() set to the input string.
std::out_of_range d("Out of range exception");
std::cout << "d.what() = " << d.what() << std::endl;
throw d;

catch (std::exception e) // Captured by value

std::cout << e.what() << std::endl;





If I compile it with g++ -std=c++17 and with Visual C++ I get different behaviors. With the first it prints d.what() = Out of range exceptionnstd::exception, while the second it prints d.what() = Out of range exceptionnOut of range exception.



In principle there could be slicing when the std::out_of_range is captured by value and converted to the std::exception type. This means that I could expect not getting the same behavior as an object from std::out_of_range object when printing its what().



Question: The part that I don't know how to explain is getting different behaviors for the two compilers. Is this because this slicing is undefined behavior in the C++ standarization, or is it that one of these two compilers is not complying with it?



Extra observation: I just noticed that in this link there is no mention of the class std::exception having a constructor that inputs a const char* const &, while in the Microsoft website they include it. My accidental example shows that they indeed implemented these classes differently. My question is still whether they were allowed (if this behavior is undefined) or if one of them is not complying and which one.







c++ visual-c++ c++17 type-slicing






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 8 at 19:16







user647486

















asked Mar 8 at 17:11









user647486user647486

1475




1475







  • 1





    The issue isn't the slicing, IMO. It is when and where the what() is set. Is it set after the slicing occurs or before the slicing occurs? That is probably what should be investigated.

    – PaulMcKenzie
    Mar 8 at 17:48











  • @PaulMcKenzie As far as I understand (which is limited) and object of type std::out_of_range is created in the line with the throw. (One of)The constructor(s) of this class inputs the string to be the value of output by what(). Then during the catch this object is assigned to e, which is of type std::exception, a parent class of `std::out_of_range. Doesn't this mean that the slicing happens after? Let me do some experiments anyway.

    – user647486
    Mar 8 at 18:41











  • Try this answer

    – PaulMcKenzie
    Mar 8 at 18:44











  • @PaulMcKenzie I did a small change to the example. I created the std::out_of_range with its what() string, printed it before throwing. The message printed is the one passed to its constructor. However, after catching the slicing changed the message, when compiling with g++. With VisualC++ it prints the same message both times.

    – user647486
    Mar 8 at 18:47






  • 1





    @zett42 In the question it is said why: By accident. But well, a happy accident because it let me to learn something I had not seen.

    – user647486
    Mar 8 at 19:24













  • 1





    The issue isn't the slicing, IMO. It is when and where the what() is set. Is it set after the slicing occurs or before the slicing occurs? That is probably what should be investigated.

    – PaulMcKenzie
    Mar 8 at 17:48











  • @PaulMcKenzie As far as I understand (which is limited) and object of type std::out_of_range is created in the line with the throw. (One of)The constructor(s) of this class inputs the string to be the value of output by what(). Then during the catch this object is assigned to e, which is of type std::exception, a parent class of `std::out_of_range. Doesn't this mean that the slicing happens after? Let me do some experiments anyway.

    – user647486
    Mar 8 at 18:41











  • Try this answer

    – PaulMcKenzie
    Mar 8 at 18:44











  • @PaulMcKenzie I did a small change to the example. I created the std::out_of_range with its what() string, printed it before throwing. The message printed is the one passed to its constructor. However, after catching the slicing changed the message, when compiling with g++. With VisualC++ it prints the same message both times.

    – user647486
    Mar 8 at 18:47






  • 1





    @zett42 In the question it is said why: By accident. But well, a happy accident because it let me to learn something I had not seen.

    – user647486
    Mar 8 at 19:24








1




1





The issue isn't the slicing, IMO. It is when and where the what() is set. Is it set after the slicing occurs or before the slicing occurs? That is probably what should be investigated.

– PaulMcKenzie
Mar 8 at 17:48





The issue isn't the slicing, IMO. It is when and where the what() is set. Is it set after the slicing occurs or before the slicing occurs? That is probably what should be investigated.

– PaulMcKenzie
Mar 8 at 17:48













@PaulMcKenzie As far as I understand (which is limited) and object of type std::out_of_range is created in the line with the throw. (One of)The constructor(s) of this class inputs the string to be the value of output by what(). Then during the catch this object is assigned to e, which is of type std::exception, a parent class of `std::out_of_range. Doesn't this mean that the slicing happens after? Let me do some experiments anyway.

– user647486
Mar 8 at 18:41





@PaulMcKenzie As far as I understand (which is limited) and object of type std::out_of_range is created in the line with the throw. (One of)The constructor(s) of this class inputs the string to be the value of output by what(). Then during the catch this object is assigned to e, which is of type std::exception, a parent class of `std::out_of_range. Doesn't this mean that the slicing happens after? Let me do some experiments anyway.

– user647486
Mar 8 at 18:41













Try this answer

– PaulMcKenzie
Mar 8 at 18:44





Try this answer

– PaulMcKenzie
Mar 8 at 18:44













@PaulMcKenzie I did a small change to the example. I created the std::out_of_range with its what() string, printed it before throwing. The message printed is the one passed to its constructor. However, after catching the slicing changed the message, when compiling with g++. With VisualC++ it prints the same message both times.

– user647486
Mar 8 at 18:47





@PaulMcKenzie I did a small change to the example. I created the std::out_of_range with its what() string, printed it before throwing. The message printed is the one passed to its constructor. However, after catching the slicing changed the message, when compiling with g++. With VisualC++ it prints the same message both times.

– user647486
Mar 8 at 18:47




1




1





@zett42 In the question it is said why: By accident. But well, a happy accident because it let me to learn something I had not seen.

– user647486
Mar 8 at 19:24






@zett42 In the question it is said why: By accident. But well, a happy accident because it let me to learn something I had not seen.

– user647486
Mar 8 at 19:24













1 Answer
1






active

oldest

votes


















1














The object is still being sliced; you can use typeid( e ).name() to print out the actual type and it shows as std::exception. As you found, MSVC implements what() to return a pointer to a string that is set at std::exception construction time, so it's not lost when the out_of_range exception is sliced back into the base exception.



Per https://en.cppreference.com/w/cpp/error/exception/exception, what() "returns an implementation-defined string" so MSVC is free to do it this way.



To print the type, add this to your catch block:




std::cout << "e.what() = " << e.what() << " Actual type = " << typeid(
e ).name() << std::endl;







share|improve this answer























    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%2f55067913%2fslicing-stdout-of-range-to-stdexception-in-visual-studio-vs-g%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









    1














    The object is still being sliced; you can use typeid( e ).name() to print out the actual type and it shows as std::exception. As you found, MSVC implements what() to return a pointer to a string that is set at std::exception construction time, so it's not lost when the out_of_range exception is sliced back into the base exception.



    Per https://en.cppreference.com/w/cpp/error/exception/exception, what() "returns an implementation-defined string" so MSVC is free to do it this way.



    To print the type, add this to your catch block:




    std::cout << "e.what() = " << e.what() << " Actual type = " << typeid(
    e ).name() << std::endl;







    share|improve this answer



























      1














      The object is still being sliced; you can use typeid( e ).name() to print out the actual type and it shows as std::exception. As you found, MSVC implements what() to return a pointer to a string that is set at std::exception construction time, so it's not lost when the out_of_range exception is sliced back into the base exception.



      Per https://en.cppreference.com/w/cpp/error/exception/exception, what() "returns an implementation-defined string" so MSVC is free to do it this way.



      To print the type, add this to your catch block:




      std::cout << "e.what() = " << e.what() << " Actual type = " << typeid(
      e ).name() << std::endl;







      share|improve this answer

























        1












        1








        1







        The object is still being sliced; you can use typeid( e ).name() to print out the actual type and it shows as std::exception. As you found, MSVC implements what() to return a pointer to a string that is set at std::exception construction time, so it's not lost when the out_of_range exception is sliced back into the base exception.



        Per https://en.cppreference.com/w/cpp/error/exception/exception, what() "returns an implementation-defined string" so MSVC is free to do it this way.



        To print the type, add this to your catch block:




        std::cout << "e.what() = " << e.what() << " Actual type = " << typeid(
        e ).name() << std::endl;







        share|improve this answer













        The object is still being sliced; you can use typeid( e ).name() to print out the actual type and it shows as std::exception. As you found, MSVC implements what() to return a pointer to a string that is set at std::exception construction time, so it's not lost when the out_of_range exception is sliced back into the base exception.



        Per https://en.cppreference.com/w/cpp/error/exception/exception, what() "returns an implementation-defined string" so MSVC is free to do it this way.



        To print the type, add this to your catch block:




        std::cout << "e.what() = " << e.what() << " Actual type = " << typeid(
        e ).name() << std::endl;








        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 8 at 19:22









        HerrJoebobHerrJoebob

        2,0251018




        2,0251018





























            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%2f55067913%2fslicing-stdout-of-range-to-stdexception-in-visual-studio-vs-g%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

            1928 у кіно

            Захаров Федір Захарович

            Ель Греко