如果 void 实际上被定义为 `struct void {};`,那么现有的 C++ 代码有多少会被破坏
How much existing C++ code would break if void was actually defined as `struct void {};`
void
是 C++ 类型系统中的一个奇怪的疣。它是一个不完整的类型,无法完成,它有各种关于它可以使用的限制方式的神奇规则:
A type cv void
is an incomplete type that cannot be completed; such a type has an empty set of values. It is used as the return type for functions that do not return a value.
Any expression can be explicitly converted to type cv void
([expr.cast]).
An expression of type cv void
shall be used only as an expression statement, as an operand of a comma expression, as a second or third operand of ?:
([expr.cond]), as the operand of typeid
, noexcept
, or decltype
, as the expression in a return
statement for a function with the return type cv void
, or as the operand of an explicit conversion to type cv void
.
(N4778, [basic.fundamental] ¶9)
除了对所有这些奇怪的规则感到厌烦之外,由于它的使用方式有限,在编写模板时它常常成为一个痛苦的特例;通常感觉我们希望它表现得更像 std::monostate
.
让我们想象一下,标准不是上面的引文,而是说 void
类似
It's a type with definition equivalent to:
struct void {
void()=default;
template<typename T> explicit void(T &&) {}; // to allow cast to void
};
在保持 void *
魔力的同时 - 可以为任何对象添加别名,数据指针必须在 void *
.
的往返过程中存活下来
这个:
- 应该涵盖
void
类型的现有用例 "proper";
- 可能允许删除通过标准传播的相当数量的垃圾 - 例如[expr.cond] ¶2 would probably be unneeded, and [stmt.return] 将大大简化(同时仍然保持 "exception"
void
允许不带表达式的 return
和 void
的 "flowing off"函数等同于 return;
);
- 应该仍然一样有效 - 现在到处都支持空 class 优化;
- 在现代 ABI 上本质上兼容,并且编译器在旧的 ABI 上仍可以进行特殊处理。
除了兼容之外,这将提供:
- 构造、复制和移动那些空对象,消除模板中通常需要的特殊情况;
void *
上的奖励指针算法,与 char *
一样运行,这是一个常见的扩展,在处理二进制缓冲区时非常有用。
现在,除了 <type_traits>
东西可能改变的 return 值之外,这可能会破坏根据当前 (C++17) 规则格式良好的代码吗?
这个有一个提案,就是p0146: Regular Void
Presented below is a struct definition that is analogous to what is
proposed for void in this paper. The actual definition is not a class
type, but this serves as a fairly accurate approximation of what is
proposed and how developers can think about void. What should be
noticed is that this can be thought of as adding functionality to the
existing void type, much like adding a special member function to any
other existing type that didn't have it before, such as adding a move
constructor to a previously non-copyable type. This comparison is not
entirely analogous because void is currently no ordinary type, but it
is a reasonable, informal description, with details covered later.
struct void {
void() = default;
void(const void&) = default;
void& operator =(const void&) = default;
template <class T>
explicit constexpr void(T&&) noexcept {}
};
constexpr bool operator ==(void, void) noexcept { return true; }
constexpr bool operator !=(void, void) noexcept { return false; }
constexpr bool operator <(void, void) noexcept { return false; }
constexpr bool operator <=(void, void) noexcept { return true; }
constexpr bool operator >=(void, void) noexcept { return true; }
constexpr bool operator >(void, void) noexcept { return false; }
在Oulu June 2016 meeting Trip Report收到好评:
Regular void, a proposal to remove most instances of special-case treatment of void in the language, making it behave like any other type. The general idea enjoyed an increased level of support since its initial presentation two meetings ago, but some details were still contentious, most notably the ability to delete pointers of type void*. The author was encouraged to come back with a revised proposal, and perhaps an implementation to help rule out unexpected complications.
我和作者聊过,他确认基本上是在等待实施,一旦实施他计划将提案带回来。
论文中有关于更改内容和原因的广泛讨论,作为一个整体并不能真正引用,但解决的常见问题解答如下:
- Doesn't This Proposal Introduce More Special-Casing for void?
- Why Isn't sizeof(void) Equal to 0?
- Does This Break std::enable_if?
- In Practice, Would This Break ABI Compatibility?
- Doesn't constexpr_if Make Branching for void Easier?
- Isn't It Illogical to Support some-operation for void?
- Doesn't This Remove the Notion of "No Result?"
- Isn't This a Change to the Meaning of void?
void
是一个具有 空 域的类型(它没有可能的值);
struct foo { }
是一种具有 非空 域的类型(此类型有一个值)。
换句话说,void
是一个bottom type while a potential struct void {}
would be a unit type。
用第二个替换第一个基本上打破了整个世界。这与在 C++ 中决定 0 等于 1 并没有完全不同。
void
是 C++ 类型系统中的一个奇怪的疣。它是一个不完整的类型,无法完成,它有各种关于它可以使用的限制方式的神奇规则:
A type cv
void
is an incomplete type that cannot be completed; such a type has an empty set of values. It is used as the return type for functions that do not return a value. Any expression can be explicitly converted to type cvvoid
([expr.cast]). An expression of type cvvoid
shall be used only as an expression statement, as an operand of a comma expression, as a second or third operand of?:
([expr.cond]), as the operand oftypeid
,noexcept
, ordecltype
, as the expression in areturn
statement for a function with the return type cvvoid
, or as the operand of an explicit conversion to type cvvoid
.
(N4778, [basic.fundamental] ¶9)
除了对所有这些奇怪的规则感到厌烦之外,由于它的使用方式有限,在编写模板时它常常成为一个痛苦的特例;通常感觉我们希望它表现得更像 std::monostate
.
让我们想象一下,标准不是上面的引文,而是说 void
类似
It's a type with definition equivalent to:
struct void { void()=default; template<typename T> explicit void(T &&) {}; // to allow cast to void };
在保持 void *
魔力的同时 - 可以为任何对象添加别名,数据指针必须在 void *
.
这个:
- 应该涵盖
void
类型的现有用例 "proper"; - 可能允许删除通过标准传播的相当数量的垃圾 - 例如[expr.cond] ¶2 would probably be unneeded, and [stmt.return] 将大大简化(同时仍然保持 "exception"
void
允许不带表达式的return
和void
的 "flowing off"函数等同于return;
); - 应该仍然一样有效 - 现在到处都支持空 class 优化;
- 在现代 ABI 上本质上兼容,并且编译器在旧的 ABI 上仍可以进行特殊处理。
除了兼容之外,这将提供:
- 构造、复制和移动那些空对象,消除模板中通常需要的特殊情况;
void *
上的奖励指针算法,与char *
一样运行,这是一个常见的扩展,在处理二进制缓冲区时非常有用。
现在,除了 <type_traits>
东西可能改变的 return 值之外,这可能会破坏根据当前 (C++17) 规则格式良好的代码吗?
这个有一个提案,就是p0146: Regular Void
Presented below is a struct definition that is analogous to what is proposed for void in this paper. The actual definition is not a class type, but this serves as a fairly accurate approximation of what is proposed and how developers can think about void. What should be noticed is that this can be thought of as adding functionality to the existing void type, much like adding a special member function to any other existing type that didn't have it before, such as adding a move constructor to a previously non-copyable type. This comparison is not entirely analogous because void is currently no ordinary type, but it is a reasonable, informal description, with details covered later.
struct void { void() = default; void(const void&) = default; void& operator =(const void&) = default; template <class T> explicit constexpr void(T&&) noexcept {} }; constexpr bool operator ==(void, void) noexcept { return true; } constexpr bool operator !=(void, void) noexcept { return false; } constexpr bool operator <(void, void) noexcept { return false; } constexpr bool operator <=(void, void) noexcept { return true; } constexpr bool operator >=(void, void) noexcept { return true; } constexpr bool operator >(void, void) noexcept { return false; }
在Oulu June 2016 meeting Trip Report收到好评:
Regular void, a proposal to remove most instances of special-case treatment of void in the language, making it behave like any other type. The general idea enjoyed an increased level of support since its initial presentation two meetings ago, but some details were still contentious, most notably the ability to delete pointers of type void*. The author was encouraged to come back with a revised proposal, and perhaps an implementation to help rule out unexpected complications.
我和作者聊过,他确认基本上是在等待实施,一旦实施他计划将提案带回来。
论文中有关于更改内容和原因的广泛讨论,作为一个整体并不能真正引用,但解决的常见问题解答如下:
- Doesn't This Proposal Introduce More Special-Casing for void?
- Why Isn't sizeof(void) Equal to 0?
- Does This Break std::enable_if?
- In Practice, Would This Break ABI Compatibility?
- Doesn't constexpr_if Make Branching for void Easier?
- Isn't It Illogical to Support some-operation for void?
- Doesn't This Remove the Notion of "No Result?"
- Isn't This a Change to the Meaning of void?
void
是一个具有 空 域的类型(它没有可能的值);struct foo { }
是一种具有 非空 域的类型(此类型有一个值)。
换句话说,void
是一个bottom type while a potential struct void {}
would be a unit type。
用第二个替换第一个基本上打破了整个世界。这与在 C++ 中决定 0 等于 1 并没有完全不同。