I have a method which accepts the bool variable named alarm. I need to access to some array by the index equals to alarm:
int ind = alarm; // assume here can be only '0' or '1'
But sometimes I get Access violation reading location... because of my variable equals more than 1 - 3, 5, etc:

How can this be possible?
...
Update:
the problem happens as a result of a randomize memory. I use it to simulate different input data.
Complete verifiable example on Microsoft Visual Studio 2015.
Standard Win32 console application:
#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;
}
The behaviour tested and occurs on compilers from Visual Studio 2010 (v100) up to Visual Studio 2015 (v140).
Looks like I just should not use this way to simulate data, but much worse is that I cannot be sure that some bool variable can be casted to 0-1.
You probably have undefined behavior somewhere in the code that is calling setAlarmSwitch.
In C++, an integer value when converted to bool takes the value false/true, which when promoted back to an integer type, become 0/1.
But that doesn't mean that bool is actually stored or passed in function calls as a single bit. In fact, most ABIs have a minimal width per argument (usually the width of a general-purpose register), and any shorter integral types are promoted to it.
To illustrate the issue:
#include <iostream>
void printBool(bool x) {
std::cout << x << std::endl;
}
int main() {
int i = 5;
printBool(i);
((void(*)(int))printBool)(i); // UB
}
Will print:
1
5
The assumption the compiler makes is that a bool argument can only contain the values 0/1 because if you follow the rules there would never be any other value passed in. It's only possible to pass another value by breaking the rules.
So then:
Using a
boolvalue in ways described by this International Standard as “undefined,” such as by examining the value of an uninitialized automatic object, might cause it to behave as if it is neithertruenorfalse.
Your example with reinterpret_cast on the other hand is another issue, I believe a bug in MSVC. It is working fine in GCC and clang.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With