我有一个接受名为alarm
的bool变量的方法。我需要通过索引等于alarm
来访问某个数组:
int ind = alarm; // assume here can be only '0' or '1'
但有时我得Access violation reading location...
,因为我的变量等于1 - 3,5等等:
这怎么可能呢?
...
更新
问题是由于随机存储器而发生的。我用它来模拟不同的输入数据
Microsoft Visual Studio 2015上完整的可验证示例。
标准Win32控制台应用程序:
#include "stdafx.h"
#include <stdint.h>
#include <stdlib.h>
static void randomize_memory(void* pointer, size_t size)
{
uint8_t* byteArray = reinterpret_cast<uint8_t*>(pointer);
for (int i = 0; i < size; i++)
{
byteArray[i] = rand() % 0xff;
}
}
struct MyStruct
{
double a = 0;
float b = 0;
bool flag = false;
};
int main()
{
while(true)
{
MyStruct st;
randomize_memory(&st, sizeof(st));
bool tmp = st.flag;
int ind = tmp;
if (ind > 1)
__debugbreak();
}
return 0;
}
在Visual Studio 2010(v100)到Visual Studio 2015(v140)的编译器上测试并发生的行为。
看起来我不应该用这种方式来模拟数据,但更糟糕的是我无法确定某些bool变量可以被转换为0-1。
答案 0 :(得分:4)
您可能在代码that is calling setAlarmSwitch
中的某处有未定义的行为。
在C ++中,转换为 bool
时的整数值取值false
/ true
,当提升回整数类型时,变为{ {1}} / 0
。
但这并不意味着1
实际上是作为单个位存储或传递给函数调用。事实上,大多数ABI的每个参数的宽度最小(通常是通用寄存器的宽度),任何较短的整数类型都提升。
说明问题:
bool
将打印:
#include <iostream>
void printBool(bool x) {
std::cout << x << std::endl;
}
int main() {
int i = 5;
printBool(i);
((void(*)(int))printBool)(i); // UB
}
编译器的假设是1
5
参数只能包含值bool
/ 0
,因为如果遵循规则,就不会传入任何其他值。它是只能通过违反规则传递另一个值。
所以then:
将本国际标准所描述的方式中的
1
值用作“未定义”,例如通过检查未初始化的自动对象的值,可能会使其表现得好像既不是bool
也不是true
。
另一方面,false
的示例是另一个问题,我相信MSVC中的一个错误。它在GCC和clang中运行良好。
答案 1 :(得分:0)
在C ++中,Public void Function() throws ioexcption
Update table a set values
Update table b set values
Insert into c values
Insert into d values
Many more updates and inserts
Function ends
是一个整数类型,这意味着可以将bool
或int
数据(例如)隐式转换为float
类型。 bool
值被视为Zero
,false
被视为non-zero
。例如,语句 -
true
如果您希望bool a = 0; // false
bool b = 10; // true
bool c = 3.2; // true
值(警报)为0(假)或1(真),那么您可以修改以下函数:
bool
答案 2 :(得分:0)
bool
的值只能是true
或false
。但是表示是实现定义的。
如果将任何变量的内存设置为不是变量的有效表示(根据该实现定义),并且您尝试读取变量,则会导致未定义的行为,这是您正在观察的内容。
您应该能够通过检查编译器文档来确认它,但编译器可能会说“所有位0 = false
,所有位1 = true
,任何其他表示无效”