This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.

3867. Should std::basic_osyncstream's move assignment operator be noexcept?

Section: 31.11.3.1 [syncstream.osyncstream.overview] Status: C++23 Submitter: Jiang An Opened: 2023-01-29 Last modified: 2023-11-22

Priority: Not Prioritized

View all other issues in [syncstream.osyncstream.overview].

View all issues with C++23 status.

Discussion:

The synopsis of std::basic_osyncstream (31.11.3.1 [syncstream.osyncstream.overview]) indicates that it's member functions behave as if it hold a std::basic_syncbuf as its subobject, and according to 16.3.3.4 [functions.within.classes], std::basic_osyncstream's move assignment operator should call std::basic_syncbuf's move assignment operator.

However, currently std::basic_osyncstream's move assignment operator is noexcept, while std::basic_syncbuf's is not. So when an exception is thrown from move assignment between std::basic_syncbuf objects, std::terminate should be called.

It's clarified in LWG 3498 that an exception can escape from std::basic_syncbuf's move assignment operator. Is there any reason that an exception shouldn't escape from std::basic_osyncstream's move assignment operator?

[2023-02-06; Reflector poll]

Set status to Tentatively Ready after seven votes in favour during reflector poll.

[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4928.

  1. Modify 31.11.3.1 [syncstream.osyncstream.overview] as indicated:

    namespace std {
      template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
      class basic_osyncstream : public basic_ostream<charT, traits> {
      public:
        […]
        using syncbuf_type = basic_syncbuf<charT, traits, Allocator>;
        […]
        
        // assignment
        basic_osyncstream& operator=(basic_osyncstream&&) noexcept;
    
        […]
      
      private:
        syncbuf_type sb; // exposition only
      };
    }