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

### 3399. `basic_syncbuf::emit()` + Qt's `#define emit` = Big Bada-Boom

Section: 29.11.2.1 [syncstream.syncbuf.overview] Status: NAD Submitter: Marc Mutz Opened: 2019-02-14 Last modified: 2020-11-09

Priority: Not Prioritized

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

View all issues with NAD status.

Discussion:

The current IS contains a function called `emit()` (in `basic_syncbuf`, added by P0053).

`emit` is a macro in pervasive use in every Qt program. `#include`'ing `<osyncstream>` after any Qt header would break, because `emit` was `#define`'d to nothing by the Qt headers.

It is understood that the committee cannot check every 3rd-party library out there that chooses (badly, as I’d readily concur) to `#define` a macro of all-lowercase letters, but the `min`/`max` issue in the Windows headers caused so much pain for our users, that we probably should avoid a breakage here, for the benefit of our users that have to work Qt.

It also doesn’t seem like `emit()` is a particularly mandatory name for the syncbuf function. Since it returns `bool`, it could just as easily be called `try_emit()` and the issue would be solved.

Suggested approach:

In `basic_syncbuf`, rename `bool emit()` to `bool try_emit()`. In `basic_osyncstream`, where the function doesn't return `bool`, but sets the stream's `failbit`, rename `void emit()` to `void emit_or_fail()`.

[2020-02-14, Prague]

The issue was send to LEWG, who made the following poll:

> We're open to renaming `osyncstream::emit()` (and related).

> >     SF F N A SA
> >     1  1 5 8 20

[2020-11-09 Status changed: Tentatively NAD → NAD.]

Proposed resolution:

This wording is relative to N4849.

1. Modify 29.7.5.5 [ostream.manip] as indicated:

   >     template<class charT, class traits>
   >       basic_ostream<charT, traits>& flush_emit(basic_ostream<charT, traits>& os);

   > > -12- Effects: Calls `os.flush()`. Then, if `os.rdbuf()` is a `basic_syncbuf<charT, traits, Allocator>*`, called `buf` for the purpose of exposition, calls `buf->try_emit()`.

2. Modify 29.11.2.1 [syncstream.syncbuf.overview] as indicated:

   >     […]
   >     // 29.11.2.4 [syncstream.syncbuf.members], member functions
   >     bool try_emit();
   >     streambuf_type* get_wrapped() const noexcept;
   >     […]

   > > -1- Class template `basic_syncbuf` stores character data written to it, known as the associated output, into internal buffers allocated using the object's allocator. The associated output is transferred to the wrapped stream buffer object `*wrapped` when `try_emit()` is called or when the `basic_syncbuf` object is destroyed. Such transfers are atomic with respect to transfers by other `basic_syncbuf` objects with the same wrapped stream buffer object.

3. Modify 29.11.2.2 [syncstream.syncbuf.cons] as indicated:

   >     ~basic_syncbuf();

   > > -7- Effects: Calls `try_emit()`.

   > > -8- Throws: Nothing. If an exception is thrown from `try_emit()`, the destructor catches and ignores that exception.

4. Modify 29.11.2.3 [syncstream.syncbuf.assign] as indicated:

   >     basic_syncbuf& operator=(basic_syncbuf&& rhs) noexcept;

   > > -1- Effects: Calls `try_emit()` then move assigns from `rhs`. After the move assignment `*this` has the observable state it would have had if it had been move constructed from `rhs` (29.11.2.2 [syncstream.syncbuf.cons]).

5. Replace in 29.11.2.4 [syncstream.syncbuf.members] all occurrences of `emit()` by `try_emit()` (five occurrences)

6. Replace in 29.11.2.5 [syncstream.syncbuf.virtuals] all occurrences of `emit()` by `try_emit()` (three occurrences)

7. Modify 29.11.3.1 [syncstream.osyncstream.overview] as indicated:

   >     […]
   >     // 29.11.3.3 [syncstream.osyncstream.members], member functions
   >     void emit_or_fail();
   >     streambuf_type* get_wrapped() const noexcept;
   >     […]

8. Replace in 29.11.3.2 [syncstream.osyncstream.cons] all occurrences of `emit()` by `emit_or_fail()` (three occurrences)

9. Replace in [syncstream.osyncstream.assign] all occurrences of `emit()` by `emit_or_fail()` (two occurrences)

10. Replace in 29.11.3.3 [syncstream.osyncstream.members] all occurrences of `emit()` by `emit_or_fail()` (six occurrences)