让 bool 方法返回其他整数
Posted
技术标签:
【中文标题】让 bool 方法返回其他整数【英文标题】:Let a bool method return other integer 【发布时间】:2020-02-16 06:40:34 【问题描述】:class I
public:
virtual bool F() = 0;
;
class A :public I
public:
virtual bool F()
int i = 2;
return i;
;
void test()
A a;
int i=a.F();
std::cout << i;
class I 是一个不易更改的协议。
想要传递比真/假更多的信息,所以想在 C++ 中使用 bool 的 uint8_t 属性。
但是编译器(VS2019/VS2017)在返回之前在 bool 方法的末尾添加了将整数转换为 0 或 1 的指令。调用方没有转换(只有一个 movzx eax, al 指令),这很好。
在bool方法的末尾有没有像编译标志或者一些嵌入的汇编代码这样的方法,让bool方法返回0/1以外的整数?
【问题讨论】:
如果您更改A
中的覆盖可以返回的值,则需要调整 F()
的每个调用站点以处理返回值的更改,因为它可能会调用 F
on一个A
。因此,无论如何您都必须更改F()
的每次使用,因此您可以通过更改A
和I
中声明的返回类型以相同的工作量来干净地完成它。
@walnut 这是基于任何现有调用者使用返回值作为布尔值的猜测。这个猜测很有可能是真的。我们现在可以假设它是真的吗?
取决于 ABI 如何定义 bool
值的传递,调用者可以假设传递的寄存器/堆栈位置保证只包含值零或一。如果您违反此保证,则程序可能无法正常运行。看看this recent reddit post 准确描述了这样一个bool
错误以及调试的难度。
我不知道 Windows ABI 对此有什么特别要说的,也许你很幸运,这在技术上是可行的,但无论如何我强烈建议不要使用这种诡计。
@walnut 谢谢你的提醒,会关心这个。现在真的想以某种方式完成这项工作,而不是生产系统。现在更改协议的主要问题是:甚至很难找到更改的位置,并且可能会出现编译错误的噩梦。您确定更改协议不会引发错误吗?
【参考方案1】:
简单的免责声明是,这个答案对生产使用没有好处。它使用通常未定义的行为。
您可以使用 reinterpret_cast
将返回值转换为布尔值,而无需实际触发 bool
构造函数(因此不会将实际值更改为 0/1)。
class A :public I
public:
virtual bool F()
int i = 2;
return *reinterpret_cast<bool *>(&i);;
;
【讨论】:
以上是关于让 bool 方法返回其他整数的主要内容,如果未能解决你的问题,请参考以下文章