How bool variable value can be equals 5? - c++

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 bool value 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 neither true nor false.
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.

In C++, bool is an integral type, that means it is possible to implicitly convert int or float data (for example) to bool type. Zero value is treated as false, and non-zero is treated as true. For example, the statements-
bool a = 0; // false
bool b = 10; // true
bool c = 3.2; // true
If you want your bool value (alarm) to be either 0(false) or 1(true), then you may revise the fuinction as below:
void StatusParameter::setAlarmSwitch(int ialarm)
{
bool alarm = (ialarm != 0); // value 5 is converted to 1
ber_print_func;
set_bold(alarm);
int ind = (int)alarm;
set_suffix(LimitSwitchSuffix[ind]);
Ber::setElementColor(m_label, LimitSwitchColor[ind]);
}

The value of a bool can only be true or false. However the representation is implementation-defined.
If you set any variable's memory to something which is not a valid representation for the variable (according to that implementation definition), and you try to read the variable, it causes undefined behaviour which is what you are observing.
You should be able to confirm it by checking the compiler documentation, but the compiler may have said something like "all bits 0 = false, all bits 1 = true, any other representation invalid".

Related

C++ 17 in VS causes variable (re)evaluation bug which does not exist in c++14

use of a function returning an integer and (possibly) modifying a base pointer causes undesired behavior in returning the intended member of an array.
this concerns quite old legacy code; modern options using containers will solve the problem (No need to tell me, please!), but I want to point this out and ask whether the behavior is intentional under C++17, as contrasted with up to and including C++14.
The code looks like:
// dosomething() returns an integer.
// ArrayPointer is a class member
somememberfunction(args)
{
...
return ArrayPointer[dosomething()];
}
The problem arises from the fact that dosomething() will change ArrayPointer and the old value of ArrayPointer is used instead of the new (under C++17, not under C++14).
The workaround is to define an intermediate variable:
const int index=dosomething();
return ArrayPointer[index];
The question is: is there an explanation (depending on the standard), or is this to be regarded as a bug, rather than just undesired behavior from my point of view?
PS: complet(er C) code, as requested, mind the non-essential parts, variable declarations omitted:
struct BKPRArray // struct for applying meteocorrection
{
double *findprarray(const char *bks)
{
// check earlier allocations (NR)
for (int n = 0; n < arrays; n++)
if (!_stricmp(this->bk[n], bks))
{
if (!PRarray[n]) PRarray[n] = (NUMTYPE*)calloc(FL_alloced, sizeof(NUMTYPE));
return PRarray[n];
}
// combined return statement will fail under C++17 by using the old value of PRarray.
// This MAY be caused by order of evaluation, rule 17: https://en.cppreference.com/w/cpp/language/eval_order
// allocate and prepare (preparation code omitted) a new array.
//return PRarray[addarray(bks, defaultMeteoCorrection)];
const auto index = addarray(bks, defaultMeteoCorrection);
return PRarray[index]; // zet factor op +20%, want bk niet specifiek vermeld bij input.
}
....
int addarray(const char *bks, const double fact = defaultMeteoCorrection)
{
PRarray = (double**)realloc(PRarray, (arrays + 1) * sizeof(*PRarray));
if (FL_alloced) PRarray[arrays] = (NUMTYPE*)calloc(FL_alloced, sizeof(NUMTYPE));
else PRarray[arrays] = NULL;
...
return arrays++;
}
....
private:
double **PRarray; // etc.
};
Order of evaluation between ArrayPointer and dosomething() is unspefified before C++17. (So the fact that it "works" in C++14 is by "chance").
In C++17, ArrayPointer should be evaluated before dosomething().
see Order of evaluation, Rule 17.

Incrementing a pointer while reading it?

The following code comes from Arduino's "Print.cpp":
size_t Print::print(const __FlashStringHelper *ifsh)
{
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
size_t n = 0;
while (1) {
unsigned char c = pgm_read_byte(p++);
if (c == 0) break;
n += write(c);
}
return n;
}
The __FlashStringHelper is basically a char array or string literal which is stored in PROGMEM (program memory) instead of RAM. It is declared as in WString.h:
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
I am interested in the unsigned char c = pgm_read_byte(p++); line and more spesifically the (p++) part. I assume that the value of the pointer p is read here and is also incremented by one byte here so that all the bytes in *ifsh can be read one after the other. Am I correct with that?
So I have 2 question considering the above;
What is the sequence in normal C/C++ compilers and what is the sequence in Arduino? Is the value first read and then the pointer incremented? Or is it the other way around?
Is the sequence always the same for C/C++ compilers or will it
differ between them?
The expression pgm_read_byte(p++) is equivalent to
pgm_read_byte(p);
p += 1;
And all C or C++ compilers that follow the standard will behave that way.
It's defined by C++ standard and:
It's the same (in this case it's post increment so it will happen after reading value from p)
Always the same.
Regarding the second question, this is from c89 standard:
The result of the postfix ++ operator is the value of the operand. After the result is obtained, the value of the operand is incremented.
I somehow believe that this is true for all newer c versions as well as cpp.
Arduino uses the avr-gcc compiler. So i can guess you can safely assume:
A = p++ is equal to A = p; p++;
The post-increment operator (i.e. variable++) will increment the variable but return the old value of the variable. It is equivalent to:
SomeType PostIncrement(SomeType& v)
{
SomeType oldValue = v;
v = v + 1;
return oldValue;
}
Example:
int x = 5;
int y = x++;
// Here x is 6 while y is 5 (i.e. the old value of x)
When you use post-increment on a variable you pass in a function call, the function will be called with the old value. Still the increment is done before the function call because the arguments will be fully evaluated before the call.
Example:
void f(int y)
{
// When execution arrives here, x is 6 while y is 5 (i.e. the old value of x)
}
int main()
{
int x = 5;
f(x++);
return 0;
}

How to use C++11 enum class for flags

Say I have such a class:
enum class Flags : char
{
FLAG_1 = 1;
FLAG_2 = 2;
FLAG_3 = 4;
FLAG_4 = 8;
};
Now can I have a variable that has type flags and assign a value 7 for example? Can I do this:
Flags f = Flags::FLAG_1 | Flags::FLAG_2 | Flags::FLAG_3;
or
Flags f = 7;
This question arises because in the enum I have not defined value for 7.
You need to write your own overloaded operator| (and presumably operator& etc.).
Flags operator|(Flags lhs, Flags rhs)
{
return static_cast<Flags>(static_cast<char>(lhs) | static_cast<char>(rhs));
}
Conversion of an integer to an enumeration type (scoped or not) is well-defined as long as the value is within the range of enumeration values (and UB otherwise; [expr.static.cast]/p10). For enums with fixed underlying types (this includes all scoped enums; [dcl.enum]/p5), the range of enumeration values is the same as the range of values of the underlying type ([dcl.enum]/p8). The rules are trickier if the underlying type is not fixed - so don't do it :)
It's maybe better to make use of std::underlying_type instead of hard-coding char type.
Flags operator|(Flags lhs, Flags rhs) {
return static_cast<Flags>(
static_cast<std::underlying_type<Flags>::type>(lhs) |
static_cast<std::underlying_type<Flags>::type>(rhs)
);
}
Now, you can change the underlying type of your enumeration without needing to update that type in every bitwise operator overload.
It should handle any enumeration type. I'm not sure it doesn't have any side effects and is completely valid C++ code. Let me know if there are some issues.
template<class T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
constexpr T operator|(T lhs, T rhs)
{
return static_cast<T>(
static_cast<std::underlying_type<T>::type>(lhs) |
static_cast<std::underlying_type<T>::type>(rhs));
}
Please don't do this. If you need to do this, enum classs probably aren't what you need.
#T.C. showed you how to do it so long as you specify underlying type, but you will run into places where your program does things it just shouldn't.
An example is where you use a switch and have a case for every defined enum value.
e.g.
enum class my_enum: unsigned int{
first = 1,
second = 2,
third = 4,
fourth = 8
};
int main(){
auto e = static_cast<my_enum>(static_cast<unsigned int>(my_enum::first) | static_cast<unsigned int>(my_enum::second));
switch(e){
case my_enum::first:
case my_enum::second:
case my_enum::third:
case my_enum::fourth:
return 0;
}
std::cout << "Oh, no! You reached a part of the program you weren't meant to!\n";
return 1;
}
Will output:
Oh, no! You reached a part of the program you weren't meant to!
then return the error code 1.
Which is also an example of why you should always have a default case, of course, but that isn't my point.
Of course, you could argue that so long as the user of the enum class never directly uses the value other than passing to a function; it would be a good way of restricting the values of a bitset. But I've always been a little too trustworthy and find std::uint[n]_t and some constexpr variables the best way (if a user sets an invalid bit it simply does nothing).
What you're doing just isn't really suitable for enum class, because it defeats the purpose of having a scoped enumeration. You can no longer enumerate the values if you set it to an undefined one.
I realize this question is a bit old, but I will write out a method I have used to do this.
(If anything, if I Google this again in the future I have it documented to find again.)
Personally I like this method because intellisense (at least the VSCode version of it... I don't have Visual Studio on Linux...) will automatically pick up on what you're doing and give you useful hints. Also, it avoids the use of macros, so the compiler can warn you if it is not happy. Lastly, without the comments, it isn't a lot of code. You're not making a class and setting a bunch of overloads or anything, but you're still getting the benefit of scoped enums so that you can reuse a flag name/value for another enum. Anyway onto the example.
namespace FlagsNS
{
/* This is an old/classic style enum so put it in a
namespace so that the names don't clash
(ie: you can define another enum with the values of
Flag_1 or Flag_2, etc... without it blowing up)
*/
enum Flags
{
Flag_1 = 1 << 0, //Same as 1
Flag_2 = 1 << 1, //Same as 2
Flag_3 = 1 << 2, //Same as 4
Flag_4 = 1 << 3 //Same as 8
};
}
/* This is telling the compiler you want a new "type" called Flags
but it is actually FlagsNS::Flags. This is sort of like using the
#define macro, except it doesn't use the preprocessor so the
compiler can give you warnings and errors.
*/
using Flags = FlagsNS::Flags;
//Later in code.... so int main() for example
int main()
{
//If you don't mind c-style casting
Flags flag = (Flags)(Flags::FLAG_1 | Flags::FLAG_2 | Flags::FLAG_3);
//Or if you want to use c++ style casting
Flags flag = static_cast<Flags>(Flags::FLAG_1 | Flags::FLAG_2 | Flags::FLAG_3);
//Check to see if flag has the FLAG_1 flag set.
if (flag & Flags::FLAG_1)
{
//This code works
}
}
The code in question doesn't compile. But you can do something like this,
enum class Flags : char
{
FLAG_1 = 1,
FLAG_2 = 2,
FLAG_3 = 4,
FLAG_4 = 8,
};
int main() {
Flags f = static_cast<Flags>(7);
Flags f1 = static_cast<Flags>( static_cast<char>(Flags::FLAG_1) | static_cast<char>(Flags::FLAG_2) | static_cast<char>(Flags::FLAG_3) );
return 0;
}
and it works
At this point, It probably makes sense to define your own class to handle this.
/** Warning: Untested code **/
struct Flag {
static Flag Flag_1;
static Flag Flag_2;
static Flag Flag_3;
static Flag Flag_4;
Flag operator = (Flag);
private:
char const value;
};
Flag operator | (Flag, Flag);

what is the value of an array element if I don't assign it myself

what would be the result if I wrote this
int array1[2];
cout << array1[0] ;
and how can I do this pseudocode :
if array1[0] doesn't have a value then assign its value to 1
I'm using C++ on DevCPP
The elements of array are uninitialized, and it is undefined behaviour to read them before writing to them. Your program is ill-formed. There is no way to "check" for this; it is your responsibility to write a correct program.
The initial value of unassigned array values is undefined (unless the array element type is a class/struct, in which case the default constructor will be called for each array element). In your first example, the behavior is undefined since you have not initialized the array element before using it.
If you want to retain an "unassigned" status then you need to use a class that encapsulates this, for example using the nullable pattern for value types.
Consider using Boost.Optional: you'd declare the array as boost::optional<int> array1[2]; and then you can test if (array1[0]) to see if that particular element has a value.
There is one point that the answers I'm seeing thus far seem to have missed. It depends on where your array is defined.
If the array is local to a function, like:
int f() {
int array1[2];
cout << array1[0] ;
}
...then the other answers are correct: the content of array1 contains unspecified values, and your attempt to read the value and send it to cout gives undefined behavior.
On the other hand, you may have defined array1 as a global variable:
int array1[2];
int f() {
cout << array1[0];
}
In this case, the content of array1 is required to be initialized to 0 for any arithmetic type (or NULL for an array of pointers). In a case like this, writing out the value in array1[0] is perfectly fine and gives defined results -- it must be 0. In this case, there is no any way to tell whether an element of an array containing the value 0 has that value because it was automatically initialized to 0, or was assigned that value later.
If you really need to know whether a value has been written to a variable, it's possible to write a class that will do that:
template <class T>
class value {
T val;
bool assigned;
public:
value(T const init=T()) : assigned(false), val(init) {}
value &operator=(T const &t) {
assigned = true;
val = t;
}
operator T() { return val; }
bool was_assigned() { return assigned; }
};
// ...
value<int> array2[2];
if (!array2[0].was_assigned())
array2[0] = 1;
It's usually easier and more efficient to just define the type to always start out initialized to a known value, so you never really care about whether it's been assigned to or not though. In short, although this supports what you've asked for, my immediate reaction is that there's probably a better/cleaner way to accomplish your ultimate goal. Before you even consider using something like this, I'd strongly recommend stepping back from what you're doing, and trying to figure out if there's a better way to do it. My guess is that there is/will be (and if you can't find it, you might want to ask another question, telling us about why you're trying to do this, to see if somebody can see a more direct way to accomplish your goal).
As far I remember that depend on the OS
As other users said, you need to initialize a then use a for loop to test each value one by one and modify them, if they fulfill a condition, I leave you a C snippet:
/* Variable declaration and initialization to 0s (You can use another value as default )*/
int a[ 5 ] = { 0 };
/* If the array[ i ] has 0 as value */
for( i = 0; i < 5; i++){
if ( a[ i ] == 0 ){
a[ i ] = 1;
}
}
If you don't initialise the element yourself, the element will obtain the value from the memory location it is stored on now (and will most probably convert it to its data type). Consider this program :
#include <iostream>
using namespace std;
int foo(int A[])
{
cout << A[0] << A[1];
}
int main()
{
int array[2];
foo(array);
}
This will give the output 00.
But now consider this code :
int main()
{
int array[2];
cout << array[0] << array[1];
}
It will give some random integer output. This is so because the uninitialised array picks up the value stored on the memory location it now occupies. You can check its memory adress by &array[0] and print it in different data types for some thought provoking questions.
eg: cout << &array[0] << char(array[0]) << bool(array[0]) etc.

what will be the default value of an uninitialized boolean value in c++

Suppose I have a struct called foo_boolean that contains some boolean values:
struct foo_boolean {
bool b1;
bool b2;
};
If I define a variable of type foo_boolean without initializing it, what will the default value of the member variables be? (i.e., true, false, or a random value of the two.)
It depends on how you create it. If the struct is constructed by default-initialization e.g.
void foo () {
fool_boolen x; // <---
then the values will be undefined (bad things will happen if you read it before setting a value).
On the other hand, if the struct is constructed by value-initialization or zero-initialization e.g.
fool_boolen x; // <--
void foo2 () {
static fool_boolen y; // <--
fool_boolen z = fool_boolen(); // <--
then the values will be zero, i.e. false.
The value of the bool will is undefined. It will be whatever else was on the stack before it, which is sometimes zeroed out if nothing has used it previously.
But again, it is undefined, which means it can be either true or false.
If you need a default value, you can do:
struct fool_bool {
bool b1;
bool b2;
fool_bool() {
b1 = true;
b2 = false;
}
};
This makes b1 true by default, and b2 false.
From Standard docs, 3.9.1.6.
Values of type bool are either true or false.47)
47)
Using a bool value in ways described by this International Standard as “undefined,” such as by examining the value of an uninitialized automatic
variable, might cause it to behave as if it is neither true nor false.
So, it is undefined..
It will produce random numbers, Why? because i tested it with g++:
#include <iostream>
using namespace std;
struct fool_bool
{
bool a;
bool b;
};
int main(int argc, char **argv)
{
fool_bool fb1;
cout << fb1.a << " : " << fb1.b << endl;
}
the first test showed me 121, 235 and the second one showed me, 34, 331
so it will be easy to figure it out!
if you mean bool the initial value is unknown.
According to my understanding,
if u declare the object as global or static then the values should be initialized to false.
Otherwise the values are not initialized (basically could be either true/false).
As many already said, in this case, the value of bool will be undefined.
On top of that bool being implementation dependant you can hardly guess what might be the outcome knowing that on top of that the bool will take the value on the stack.
If we assume that we have 1 byte to store the bool and that we have 0 for false and otherwise for true, you will have:
probability of 254/255 of getting a true
probability of 1/255 of getting a false
So with that specific implementation, even though you won't know for certain, you will probably get a true (of course it also depends on what was on that position in the stack).
But it's just conjecture at this point: the answer is undefined as said by everyone else.
You will have either trueor false.
Interesting when I created a struct with two booleans
struct test {
bool x;
bool y;
};
Added them to a vector and iterated later - only setting the value x to true and printing both of them found the default was generally '0' indicating false but when one of them was set to true explicitly the other member also resulted in a '1' indicating that the last value from stack was being used.
This could have been such a painful bug - glad was caught by some unit testing.
In VS 2012, you will encounter error C4700 if you don't initialize the bool variable: uninitialized local variable 'temp' used
However, in VS 2005 it will allow you to build, but during runtime you will encounter this error: Run-Time Check Failure #3 - The variable 'a' is being used without being defined.