GithubHelp home page GithubHelp logo

papers's People

Contributors

ahh avatar bigcheese avatar billyoneal avatar chicoxyzzy avatar daveedvdv avatar je4d avatar jfbastien avatar jwakely avatar kohler avatar nschonni avatar ogiroux avatar rcseacord avatar sickeroni avatar viboes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

papers's Issues

N4455: Incorrect claim about fetch_add(0)

As I understand it, the fetch_add is turned into 2 instructions: mfence and mov

The text here claims it turns into just a mov

This x86 assembly reduces contention by replacing fetch_add—an instruction requiring exclusive cache line access—to a simple movl

D0323r6: Do we really want in-place construction for expected<void, E>?

Do we want really to support in-place construction for expected<void, E>

```c++
    constexpr explicit expected<void, E>::expected(in_place_t);
```

as it has no added value respect the default constructor?

expected<void, E> x {in_place};

The current wording supports it and is coherent respect to

expected<void, E> x;
x.emplace();

D0323r5: unexpected should support heterogeneous conversions

template <class E>
class unexpected {
public:
    unexpected() = delete;
    constexpr unexpected(const unexpected&) = default;
    constexpr unexpected(unexpected&&) = default;    
    
    template <class Err>
    constexpr explicit unexpected(Err&&);

    template <class Err>
    constexpr EXPLICIT unexpected(const unexpected<Err>&);
    template <class Err>
    constexpr EXPLICIT unexpected(unexpected<Err>&&);

    constexpr unexpected& operator=(const unexpected&);
    constexpr unexpected& operator=(unexpected&&) noexcept(see below);

    template <class Err>
    constexpr unexpected& operator=(const unexpected<Err>&);
    template <class Err>
    constexpr unexpected& operator=(unexpected<Err>&&);
    
    constexpr const E& value() const& noexcept;
    constexpr E& value() & noexcept;
    constexpr const E&& value() const&& noexcept;
    constexpr E&& value() && noexcept;
    
    void swap(unexpected&) noexcept(see below);
private:
    E val; // exposition only
};

D0323r6: expected<T,E> and [[nodiscard]] attribute

All functions returning expected<T,E> should be declared [[nodiscard]] or expected<T,E> should be declared with attribute [[nodiscard]].

This is particular important for expected<void,E> as the user could forget to check if there is an error as there is no value to retrieve.

P0323R9: Various Omissions and Errors

Under Section 1.6

  1. template<class U, class G> explicit(see below) constexpr expected(const expected<U, G>& rhs) : Are the constraints involving E and G still applicable when T and U are cv void?

  2. template<class U, class G> explicit(see below) constexpr expected(expected<U, G>&& rhs) : Are the constraints involving E and G still applicable when T and U are cv void?

  3. template<class... Args> constexpr explicit expected(unexpect_t, Args&&... args); : Should be "with the arguments in_place, std::forward<Args>(args)...."

  4. template<class U, class... Args> constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args); : Should be "with the arguments in_place, il, std::forward<Args>(args)...."

Under Section 1.8

  1. expected& operator=(const expected& rhs) noexcept(see below); : noexcept specification does not match the one in the class synopsis.

  2. expected& operator=(expected&& rhs) noexcept(see below);

    • Missing std::move, should be

    move constructs an unexpected_type<E> tmp from unexpected(std::move(this->error())) (which can’t throw as E is nothrow-move-constructible)

    • For !bool(*this) && bool(rhs), missing "and set has_val to true"

    • Constraint for when T is cv void should be is_move_constructible_v<E> is true and is_move_assignable_v<E> is true.

    • Constraint for when T is not cv void should be (determined by following the logic in the table):
      is_move_constructible_v<T> && is_move_assignable_v<T> && is_move_constructible_v<E> && is_move_assignable_v<E> && (is_nothrow_move_constructible_v<E> || is_nothrow_move_constructible_v<T>)

    • The expression inside noexcept should be equivalent to:
      is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>

  3. template<class G = E> expected<T, E>& operator=(const unexpected<G>& e); : Table is inverted

  4. expected<T, E>& operator=(const unexpected<G>& e); and expected<T, E>& operator=(unexpected<G>&& e);

    • Should be e.value() instead of e.error().

    • Temporary unexpected<E> should be created from unexpected<G> before destroying val to ensure strong exception guarantee.

  5. expected<T, E>& operator=(unexpected<G>&& e);, for !bool(*this) : Missing std::move, should be "move assign unexpected(std::move(e).value()) to unex".

  6. template<class U = T> expected<T, E>& operator=(U&& v); : Missing std::move, should be

move constructs an unexpected<E> tmp from unexpected(std::move(this->error())) (which can’t throw as E is nothrow-move-constructible)

  1. Why are there no assignment operator overloads taking expected<U, G>? There are after all assignment operator overloads for std::optional taking std::optional<U>.

  2. template<class... Args> T& emplace(Args&&... args); : By following the logic under Effects, the constraint should be is_constructible_v<T, Args...> && (is_nothrow_constructible_v<T, Args...> || is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>). Upon exception, one or more arguments may be left in a post-moved state, so the "nothing changes" remark is not completely accurate.

  3. template<class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args); : By following the logic under Effects, the constraint should be is_constructible_v<T, L, Args...> && (is_nothrow_constructible_v<T, L, Args...> || is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E>) where L is std::initializer_list<U>. Upon exception, one or more arguments may be left in a post-moved state, so the "nothing changes" remark is not completely accurate.

Under Section 1.9

  1. Constraints should be is_nothrow_move_constructible_v, not is_move_constructible_v.

  2. In table, for bool(*this) && !bool(rhs) and is cv void, should be unexpected(std::move(rhs.error())) (missing .error())

Under Section 1.10

  1. constexpr T&& expected::value() && and constexpr const T&& expected::value() const&& : Should they throw bad_expected_access(std::move(*this).error()) instead, in order to allow move-only error types?

  2. value_or : Behavior and/or constraints need to be clarified when T is void. Does it ignore the argument and do nothing, or is it disabled entirely?

Under Section 1.12

  1. operator!=: Should be "expression *x != v is well-formed.

  2. operator!=: Should be "Returns: bool(x) ? *x != v : true;. If x holds an error, than is it unequal to any value v. Otherwise, !( x != v) would not be the same as x == v.

Under Section 1.14

  1. Constraints don't match those for member swap.

Under Section 1.17.1

  1. Should be Err in constraints, instead of U.

  2. template<class Err> constexpr explicit unexpected(Err&& e) : Should be unexpect_t in constraints, not unexpected.

D0323r5: What kind of type can be the T in expected<T,E>

Do we want immutable expected?
If yes, should we declare them as expected<const T, const E>?
or it is better to have a specific const_expected<T,E>?

Do we want so support volatile expected<volatile T,E>?

Granted we don't want to support references for the first version.

Are there other types we don't want to support?

D0323R9: Inconsistent requirement and effects

At

*Requires*: The expressions `*x == *y` and

*Requires*: The expressions `*x == *y` and
`unexpected(x.error()) == unexpected(y.error())` shall be well-formed and its result
shall be convertible to `bool`.

*Returns*: If `bool(x) != bool(y)`, `false`; otherwise if `bool(x) == false`,
`x.error() == y.error()`; otherwise `true` if `T1` and `T2` are *cv* `void` or `*x == *y` otherwise.

The requirement that unexpected(x.error()) == unexpected(y.error()) is well-formed is inconsistent with doing x.error() == y.error().

p0323r7 avoid explicit throw an exception, including bad_access_expected

Is p0323r7 adopted by c++23 ?

std::expected very good candidate for alternative exceptions error-code principle. But there access value methods throw the exception bad_access_expected: again the exception! std::expected already have has_value method to check this situation.

Yes, std::optional::value() also throws exception, but std::expected specially class for exception-free code, in my opinion.

I personally thought about, why can't to remove explicit throwing any exception ?

For example, std::move_only_function's call "empty" state no more throws bad_functional_call exception, it simply cause an UB.

Pls, remove bad_access_expected class, and do not throw an any exception, explicitly! Let value() cause an UB, if there error state.

D0323r6: Ill formed signatures for expected<void, E>

The following signatures are ill formed or have no sense when T void.

    constexpr const T* operator ->() const;
    constexpr T* operator ->();
    constexpr const T& operator *() const&;
    constexpr T& operator *() &;
    constexpr const T&& operator *() const &&;
    constexpr T&& operator *() &&;
    constexpr const T& value() const&;
    constexpr T& value() &;
    constexpr const T&& value() const &&;
    constexpr T&& value() &&;
    template <class U>
        constexpr T value_or(U&&) const&;
    template <class U>
        constexpr T value_or(U&&) &&;

Either all should not participate in overload resolution for expected<void, E> or maybe
expected<void::E>::value() const.

I prefer to don't define them for expected<void, E>. How to organize the wording then?
Should we use see below for the ill formed parts?

D0323r6: unexpected<E> should be trivial if E is trivial

template <class Err>
constexpr explicit unexpected(Err&& e);

Effects: Initializes val as if direct-non-list-initializing an
object of type E with the expression std::forward<Err>(e).

Remark: This constructor participates in overload resolution if and only if std::is_constructible_v<E, Err&&>

We need in addition

and is_same_v<remove_cvref_t<Err>, unexpected<E>> is false

so that unexpected<E> is trivial if E is trivial.

N4455: Undefined variable z in sample

Is this sample correct?

int x = 0;
std::atomic<int> y;
int no() {
  x = 0;
  y.store(0, std::memory_order_release);
  while (!y.load(std::memory_order_acquire));
  x = 1;
  return z;
}

(From

papers/source/N4455.bs

Lines 376 to 388 in 0ef0303

Whereas the following code must (and does!) remain the same:
<pre highlight="c++">
int x = 0;
std::atomic&lt;int&gt; y;
int no() {
x = 0;
y.store(0, std::memory_order_release);
while (!y.load(std::memory_order_acquire));
x = 1;
return z;
}
</pre>
)

z is not defined. I'm not sure if it should be defined and then assigned in the loop or if it should just return 0

D0690r0

In the enumeration of the four suggested solutions, I feel that at least for the sake of discussion, a fifth solution, described in a sidebar within p0603r0, should be mentioned: change the memory model such that data races aren't undefined behaviour, but rather, that reads of raced data produce indeterminate values, the use of which is undefined behaviour.

p0603r0 says that this is likely to be too radical a change to the memory model, though it would not in general alter program correctness, as aside from these speculative examples programs do not generally read racy data without using the values that have been read.

Adopting such a rule in general would be problematic, due for example to trap values. But a constrained proposal--for example, "byte-wise reads (which are already guaranteed to not trap) do not introduce races even in the face of concurrent writes, they merely produce indeterminate values"--would be:

  1. a good match for what hardware and software already does
  2. intuitively obvious (individual bytes are surely atomic on any real platform, so reads performed as individual bytes can't be racy)
  3. enable efficient implementations of both seqlocks and ws-queues
  4. unlike D0690r0 and p0603r0 mean that any issues with atomic<T> for large T can be ignored (since these structures would not need atomic<T> at all and hence we wouldn't care if atomic<T> needed embedded locks on some platforms)
  5. would actually live up to the title of p0603r0 by being a safe memcpy (since p0603r0's ultimate proposal, atomic<T>::nonatomic_Xxx is not itself memcpy)
  6. avoids the contradiction of giving atomic<T> non-atomic operations which is, at the very least, aesthetically displeasing.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.