A. Jiang

Results 239 comments of A. Jiang

我觉得它应该改成这样: ```C++ struct identity { template constexpr T &&operator()(T &&x) const noexcept { return (T&&)x; } }; ```

实际的 bug 应该是 `mystl::rb_tree_iterator` ~不能隐式转换成 `mystl::rb_tree_const_iterator`~ 和 `mystl::rb_tree_const_iterator` 存在双向隐式转换。 应该只能从 `mystl::rb_tree_iterator` 隐式转换成 `mystl::rb_tree_const_iterator` 而不能反过来。

首先看下是不是 debug 模式测的。 如果是的话,那原因就是标准库实现在 debug 模式增加了很多迭代器检查机制,而 MyTinySTL 没有。

> 这个问题有一定争议,不过在标准中有这样一段话: > > > **ISO/IEC 14882:2017 12.2.2 Non-static member functions(2)** > > If a **non-static** member function of a class X is called for an object that is not...

> > > 这个问题有一定争议,不过在标准中有这样一段话: > > > > **ISO/IEC 14882:2017 12.2.2 Non-static member functions(2)** > > > > If a **non-static** member function of a class X is called for...

或许 `p->baz()` 这个情况语义上就不该进行指针解引用。@adah1972 @Mq-b 要不写个 paper 给 EWG ,改掉用 `->` 访问静态成员时的等价语义?

> @frederick-vs-ja > > 原始的 CWG 315 就是你说的语义,不真正访问就不算有问题。但现在 CWG 的态度是统一处理。同一封邮件里还写到: > > > Some people are unhappy with that outcome, but CWG feels a paper to EWG with analysis and...

> > 或许 `p->baz()` 这个情况语义上就不该进行指针解引用。@adah1972 @Mq-b 要不写个 paper 给 EWG ,改掉用 `->` 访问静态成员时的等价语义? > > 关键在于**修改的价值**,为什么会空指针调用成员函数?如果是静态的,为什么不直接用类名,如果不是静态的,那更就应该让它错。 > > 为了这个问题而修改让 `->` 不等价于解引用再 `.`,有些莫名其妙了。 我应该说了: > 理由是没必要进行冗余的操作。

> 我的理解是一回事。原先的语义:不实际会发生的空指针解引用不是未定义行为。现在的语义:只要形式上写出了对空指针解引用,就是未定义行为。你的说法跟原先的语义靠拢。 原先的语义并不是“不会实际发生的空指针解引用不是未定义行为”,而(可能)是“不通过解引用的结果访问时不产生未定义行为”。解引用一直都是实际发生的。 > 原先的语义一样有灰色地带:如果一个非静态成员函数不直接或间接访问当前对象的任何数据成员,那我们可以在空指针上调用这个函数吗?实际编译器不会产生有问题的代码,但标准仍认为这是未定义行为,有些工具也能进行告警。 这个 issue 最开始的问题就是涉及静态成员函数,我觉得没有必要提及非静态成员。

> 从编译器产生代码的角度,解引用从来没发生过。从形式的角度,解引用一直存在。CWG 315 原先的合法化方式也是说 `*p` 没有做 lvalue-to-rvalue 转换就行(实际上也是有点别扭的)。 但在标准语义中它仍然是一个求值步骤,而且对常量求值是有影响的。 目前各编译器接受这个例子([Godbolt link](https://godbolt.org/z/GWcTGc97K)): ```C++ struct S { static constexpr int value = 42; }; static_assert([]{ return static_cast(nullptr)->value; }() == 42); ``` 而按照当前标准要求这是需要拒绝的。当然这可能是目前实现没有实现...