This question already has an answer here:
`std::bitset` with and without boundary checks
(1 answer)
Closed 1 year ago.
Some data are stored in a 64 bit integer. As you can see, inside the getDrvAns function I check if the bit in the position drvIdx-1 is 0 or 1. One cannot be sure if the drvIdx will have a value in the right range (1-64). However, I noticed that if we put a value higher that 64, we have a wrap-around effect as demonstrated in the code below.
My question is, is this a standard behavior? Is it safe to leave it as it is without boundary checks?
Note: If the bit is set to 0 the drive has answered.
uint64_t mDrvAns = 48822;
bool getDrvAns(int drvIdx) {
std::bitset<64> bitRepOfmDrvAns{mDrvAns};
return (bitRepOfmDrvAns[drvIdx - 1] != 0ull);
};
std::string yesOrNo(bool val) {
return ((val==false) ? "Yes" : "No");
}
int main()
{
int drvIdx = 1;
std::bitset<64> bitsOfDrvAns{mDrvAns};
std::cout << bitsOfDrvAns << std::endl;
std::cout << "Has drv " << drvIdx << " answered? " << yesOrNo(getDrvAns(drvIdx))
<< std::endl;
drvIdx = 65;
std::cout << "Has drv " << drvIdx << " answered? " << yesOrNo(getDrvAns(drvIdx))
<< std::endl;
return 0;
}
According to the documentation, out of bounds access using operator[] is Undefined Behaviour. Don't do it.
If you don't want to check the bounds yourself, call test() instead, and be prepared to handle the exception if necessary.
Related
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 3 years ago.
I understand the basic differences between prefix/postfix notation for decrement/increment operators in C++. However, there is something going on in the next example that stumps me.
The code I shared below prints the following.
5*4**3***4****2*****1
But I would have guessed it would print this.
5*4**4***3****2*****1
How is this happening? Is something going on with pushing/popping to/from the stack?
int var = 5;
cout << var-- << '*'; //prints 5 and then decrements to 4.
cout << var << "**"; //The value of var (now 4)
//is printed to the console.
//The next line prints 3***4****.
//I would have guessed it prints 4***3****.
cout << var-- << "***" << var-- << "****";
//No matter what the above line prints,
//the value of var after the above lines is 2, so...
cout << var-- << "*****" << var << endl; //...Print 2, decrement to 1
//and then 1 is finally printed.
Welcome to the strange world of undefined behaviour. Calling an increment or decrement operator twice on the same variable, in the same statement, is undefined behaviour, so don't do it :)
#include <iostream>
int main()
{
int i = 1;
// should this print 9, 10, or 12? Compilers will vary...
std::cout << (++i + ++i + ++i) << std::endl;
return 0;
}
The problem in this line:
cout << var-- << "***" << var-- << "****";
is undefined behaviour because you using post-decrement twice in a single statement.
What is the correct way to determine if a number (in my case it is a value of power of two calculated by pow(2,n)) is within the limits of values that one variable type can take? I'm doing it like this: if(pow (2,128)>std::numeric_limits<float>::max()), but this is evaluated as true although it is expected that float's maximum value is 2^128 or something more. Is there any better way to do this comparison?
For these kinds of limit checking, you can move the terms around to stay within the limits of the type.
In this case, pow(2,n) == exp(ln(2)*n) mathematically, so, rearranging terms, you can use n > ln(maxval)/ln(2)
You can take the base 2 logarithm of the maximum limit for the type of variable and compare it to n. For example: if(n > std::log2(std::numeric_limits<float>::max()). You probably don't want n to be exactly on the limit though, since I think stuff like floating point error might cause some problems.
First of all can you answer what is the result of pow(2, 128)?
The real question is what is the type for this expression?
The second question is do you know how floating point numbers work?
Take a look on this code to give you a hints:
#include <cmath>
#include <iostream>
#include <limits>
template<class T>
void printInfo(const std::string& desc, T x)
{
std::cout << desc << ' ' << typeid(x).name() << ' ' << x << std::endl;
}
int main()
{
printInfo("A", std::pow(2, 128));
printInfo("B", std::pow(2.0f, 128));
printInfo("A", std::pow(2, 128.0f));
auto c = std::pow(2.0f, 128.0f);
printInfo("C", c);
std::cout << (c > std::numeric_limits<float>::max()) << std::endl;
std::cout << (c == std::numeric_limits<float>::infinity()) << std::endl;
return 0;
}
https://wandbox.org/permlink/bHdKqToDKdC0hSvW
I recommend review documentation of numeric_limits.
And analyze this code:
#include <cmath>
#include <iostream>
#include <limits>
template<class T>
void print2exp()
{
std::cout << typeid(T).name() << '\n';
std::cout << "Radix = " << std::numeric_limits<T>::radix << '\n';
auto maxExp = std::numeric_limits<T>::max_exponent;
std::cout << "Max exp = " << maxExp << '\n';
std::cout << "2^maxExp = " << std::pow(static_cast<T>(2), static_cast<T>(maxExp)) << '\n';
std::cout << "2^(maxExp - 1) = " << std::pow(static_cast<T>(2), static_cast<T>(maxExp - 1)) << '\n';
}
int main()
{
print2exp<float>();
print2exp<double>();
print2exp<long double>();
return 0;
}
https://wandbox.org/permlink/J0hACKUKvKlV8lYK
So proper approach to this is (assuming that radix is 2):
if (x < std::numeric_limits<T>::max_exponent) {
return std::pow(static_cast<T>(2), static_cast<T>(x));
} else {
throw invalid_argument("x is to big to be use as 2^x");
}
This question already has answers here:
Swapping two variable value without using third variable
(31 answers)
Closed 6 years ago.
we usually use the
a=a+b;
b=a-b;
a=a-b;
logic to solve this code, however, if we work with int, then after say 30000 the code fails, if we take long, it fails after say 1000000 or so. My objective is, not to increase the length of the code yet, do the same operation. I have already tried using a BIT wise XOR,
a = a ^ b;
b = a ^ b;
a = a ^ b;
Still it didn't help, any ideas?
To swap a variable a and a variable b: std::swap(a, b);
Example:
int a = 10;
int b = 20;
std::cout << "Before swap\n";
std::cout << "Value of a: " << a << '\n';
std::cout << "Value of b: " << b << '\n';
std::swap(a, b);
std::cout << "After swap\n";
std::cout << "Value of a: " << a << '\n';
std::cout << "Value of b: " << b << '\n';
Output using GCC 4.9.2:
Before swap
Value of a: 10
Value of b: 20
After swap
Value of a: 20
Value of b: 10
This way of doing it uses rvalues internally, so it has next to zero overhead for other use cases and won't overflow for any primitive type ever
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the correct answer for cout << c++ << c;?
I just ouputted text, when I suddenly noticed.
#include <iostream>
int main()
{
int array[] = {1,2,3,4};
int *p = array;
std::cout << *p << "___" << *(p++) << "\n";
// output is 1__1. Strange, but I used brackets! it should be at
// first incremented, not clear.
p = array;
std::cout << *p << "___" << *(++p) << "\n";
// output is 2_2 fine, why first number was affected? I didn't intend
// to increment it, but it was incremented
p=array;
std::cout << *p << "___" << *(p + 1) << "\n";
// output is 1_2 - as it was expected
p = array;
return 0;
}
Such behaviour is strange for me, why is it so?
You are causing undefined behaviour, so anything can happen and there's no point in speculating about why.
The expression
std::cout<<*p<<"___"<<*(p++)<<"\n"
Is one example: the order of evaluation of all the things between << is unspecified, so *p and *(p++) are unsequenced with respect to each other (i.e. the compiler is not required do do either one first). You are not allowed to modify a variable and then use it without the modification and usage being sequenced, and so this causes undefined behaviour.
The same thing applies to all the other places in that program where a variable is modified and used unsequenced separately in the same expression.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Undefined Behavior and Sequence Points
I'm having trouble understanding the order of actions when overloading the postfix operator. Let's examine the two small examples below:
int i = 0;
std::cout << std::endl << "i: " << i;
i = ++i;
std::cout << std::endl << "i: " << i;
i = i++;
std::cout << std::endl << "i: " << i;
MyClass myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = ++myObject;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
myObject = myObject++;
std::cout << std::endl << "myObject: " << myObject.getMyValue();
Two very different behaviors emerge. The output is as follows:
i: 0
i: 1
i: 2
myObject: 0
myObject: 1
myObject: 1
Different behavior, you see. Here's the outline of my overloaded-operator methods.
MyClass & MyClass::operator++ ()
{
++myValue;
return *this;
}
MyClass MyClass::operator++ (int postfixFlag)
{
MyClass myTemp(*this);
++myValue;
return myTemp;
}
Alright. Prefix makes sense. You increment whatever you need to, then return the same object, now modified, in case of assignment. But postfix is what's tripping me up. It's supposed to assign, then increment. Here we're self assigning. So with the built-in integer type, it makes sense. I assign i's value to itself, then i gets incremented. Fair enough. But let's say MyClass is a recreation of the int. It starts out at 0, gets prefix-incremented, and becomes 1. Then, the key line. myObject = myObject++. That's the same thing as myObject = myObject.operator++(int postfixFlag). It gets called. myTemp gets initialized with the value 1. It's incremented to 2. Then we return the temp. That works, if we're assigning to another object. But here I'm self-assigning, so after the increment to 2, myObject is set equal to the returned temp object initialized with the initial value, and we're back to 1! That makes sense. But it's a fundamentally different behavior.
How do I work around it? How does int do it? How is this method generally written? Do you have any comments about C++ behavior and design relating to this? Etc. I'm a little perplexed right now, since books and online examples always seem to use a variant on the method above.
Thanks for reading, and any input will be appreciated!
As others have said, with int the behaviour is undefined. But I thought I'd try to explain why for your MyClass it is not ever getting to 2.
The trick is that you are taking the following three steps in the postfix version:
Making a copy of this called myTemp (with myValue == 1).
Incrementing this->myValue (so myTemp.myValue == 1; this->myValue == 2).
Returning myTemp (with myValue == 1).
So you are modifying this, but the code that calls myObject++ is never going to see this again. It's only going to look at the value returned, which is a copy of the old myObject.
The code for operator++ is fine. The problem is how you are using it -- you shouldn't be writing the result of a pre-increment or post-increment back to the same variable (behaviour is undefined). Here is some code that might be more instructive:
int i = 0;
std::cout << "i: " << i << std::endl;
int j = ++i;
std::cout << "i: " << i << ", j: " << j << std::endl;
int k = i++;
std::cout << "i: " << i << ", k: " << k << std::endl;
MyClass myObject;
std::cout << "myObject: " << myObject.getMyValue() << std::endl;
MyClass myObject1 = ++myObject;
std::cout << "myObject: " << myObject.getMyValue()
<< ", myObject1: " << myObject1.getMyValue() << std::endl;
MyClass myObject2 = myObject++;
std::cout << "myObject: " << myObject.getMyValue()
<< ", myObject2: " << myObject2.getMyValue() << std::endl;
This prints:
i: 0
i: 1, j: 1
i: 2, k: 1
myObject: 0
myObject: 1, myObject1: 1
myObject: 2, myObject2: 1
I changed your code so that rather than assigning back to itself, it assigns to a fresh variable each time. Note that in both the int and the MyClass cases, the main variable (i/myObject) is incremented both times. However, in the pre-increment case, the fresh variable (j/myObject1) takes on the new value, while in the post-increment case, the fresh variable (k/myObject2) takes on the old value.
Edit: Just answering another part of the question, "How does int do it?" I assume this question means "what does the pre-increment and post-increment code look like in the int class, and how can I make mine the same?" The answer is, there is no "int class". int is a special built-in type in C++ and the compiler treats it specially. These types aren't defined with ordinary C++ code, they are hard-coded into the compiler.
Note: For anyone who wants to try this themselves, here is the code for MyClass that the question didn't include:
class MyClass
{
private:
int myValue;
public:
MyClass() : myValue(0) {}
int getMyValue() { return myValue; }
MyClass& operator++();
MyClass operator++(int postfixFlag);
};