Combining static assert and assert? - c++

I have a function that looks like this:
int div_round_up(int x, int y) {
/**
* This function only works for positive divisor and non-negative dividend!!
*/
assert(y > 0 && x >= 0);
if (x == 0)
return 0;
return (x - 1) / y + 1;
}
It won't work with y <= 0 or x < 0. That's ok with me, I can even dynamically check for right values, but I would like to check statically, when someone feeds it wrong values. If I defined x and y as unsigned, they would get silently converted from negative values to huge positive values which would produce erroneous result, so I don't want that. I would like to make compilation fail when someone attempts to feed it negative values like in div_round_up(variable, -7). What should I do?

To verify a number at compile time (which is what static_assert does), it has to be known at compile time. To see why this is needed, consider that something like div_round_up(read_integer_from_file(), read_keyboard_character()). The obvious drawback of doing that is that you have to know the numbers at compile time.
The easiest way is to make them template parameters, which allows you to leave the implementation of the function (almost) the same:
template<int x, int y>
int div_round_up() {
static_assert(y > 0 && x >= 0, "This function only works for positive divisor and non-negative dividend");
if (x == 0)
return 0;
return (x - 1) / y + 1;
}
It can be called as div_round_up<3, 4>() and will fail the compilation when the static_assert fires.

If you're using gcc or clang you can include a macro
#define div_round_up(a, b) (__builtin_constant_p(b) ? drus(a, b) : drud(a, b))
and two different function where drus includes a static assertion for b while drud does not.

Yeap you can do it with some magic(one nonamed russian code guru told me this trick)
#define check2(x) typedef char checkVal[(x)?1:-1];
int main() {
check2(3<4);
check2(5<4);
return 0;
}
but also in this case there is one limit. Compiler should know result of this value. In any another case it`s imossible(IMHO).

Related

how could I use the power function in c/c++ without pow(), functions, or recursion

I'm using a C++ compiler but writing code in C (if that helps)
There's a series of numbers
(-1^(a-1)/2a-1)B^(2a-1)
A and X are user defined... A must be positive, but X can be anything (+,-)...
to decode this sequence... I need use exponents/powers, but was given some restrictions... I can't make another function, use recursion, or pow() (among other advanced math functions that come with cmath or math.h).
There were plenty of similar questions, but many answers have used functions and recursion which aren't directly relevant to this question.
This is the code that works perfectly with pow(), I spent a lot of time trying to modify it to replace pow() with my own code, but nothing seems to be working... mainly getting wrong results. X and J are user inputted variables
for (int i = 1; i < j; i++)
sum += (pow(-1, i - 1)) / (5 * i - 1) * (pow(x, 5 * i - 1));
}
You can use macros to get away with no function calls restriction as macros will generate inline code which is technically not a function call
however in case of more complex operations macro can not have return value so you need to use some local variable for the result (in case of more than single expression) like:
int ret;
#define my_pow_notemp(a,b) (b==0)?1:(b==1)?a:(b==2)?a*a:(b==3)?a*a*a:0
#define my_pow(a,b)\
{\
ret=1;\
if (int(b& 1)) ret*=a;\
if (int(b& 2)) ret*=a*a;\
if (int(b& 4)) ret*=a*a*a*a;\
if (int(b& 8)) ret*=a*a*a*a*a*a*a*a;\
if (int(b&16)) ret*=a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a;\
if (int(b&32)) ret*=a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a;\
}
void main()
{
int a=2,b=3,c;
c=my_pow_notemp(a,b); // c = a^b
my_pow(a,b); c = ret; // c = a^b
}
as you can see you can use my_pow_notemp directly but the code is hardcoded so only up to a^3 if you want more you have to add it to code. The my_pow is accepting exponents up to a^63 and its also an example on how to return value in case of more complex code inside macro. Here are some (normal) ways on how to compute powers in case you need non integer or negative exponents (but to convert it to unrolled code will be insanely hard without loops/recursion):
Power by squaring for negative exponents
In case you want to get away with recursion and function calls you can use templates instead of macros but that is limited to C++.
template<class T> T my_pow(T a,T b)
{
if (b==0) return 1;
if (b==1) return a;
return a*my_pow(a,b-1);
}
void main()
{
int a=2,b=3,c;
c=my_pow(a,b);
}
As you can see templates have return value so no problem even with more complex code (more than single expression).
To avoid loops you can use LUT tables
int my_pow[4][4]=
{
{1,0,0,0}, // 0^
{1,1,1,1}, // 1^
{1,2,4,8}, // 2^
{1,3,9,27}, // 3^
};
void main()
{
int a=2,b=3,c;
c=my_pow[a][b];
}
If you have access to FPU or advanced math assembly you can use that as asm instruction is not a function call. FPU usually have log,exp,pow functions natively. This however limits the code to specific instruction set !!!
Here some examples:
How to: pow(real, real) in x86
So when I consider your limitation I think the best way is:
#define my_pow(a,b) (b==0)?1:(b==1)?a:(b==2)?a*a:(b==3)?a*a*a:0
void main()
{
int a=2,b=3,c;
c=my_pow(a,b); // c = a^b
}
Which will work on int exponents b up to 3 (if you want more just add (b==4)?a*a*a*a: ... :0) and both int and float bases a. If you need much bigger exponent use the complicated version with local temp variable for returning result.
[Edit1] ultimative single expression macro with power by squaring up to a^15
#define my_pow(a,b) (1* (int(b&1))?a:1* (int(b&2))?a*a:1* (int(b&4))?a*a*a*a:1* (int(b&8))?a*a*a*a*a*a*a*a:1)
void main()
{
int a=2,b=3,c;
c=my_pow(a,b); // c = a^b
}
In case you want more than a^15 just add sub term (int(b&16))?a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a:1 and so on for each bit of exponent.
It is a series. Replace pow() based on the previous iteration. #Bathsheba
Code does not need to call pow(). It can form pow(x, 5 * i - 1) and pow(-1, i - 1), since both have an int exponent based on the iterator i, from the prior loop iteration.
Example:
Let f(x, i) = pow(x, 5 * i - 1)
Then f(x, 1) = x*x*x*x
and f(x, i > 1) = f(x, i-1) * x*x*x*x*x
double power_n1 = 1.0;
double power_x5 = x*x*x*x;
for (int i = 1; i < j + 1; i++)
// sum += (pow(-1, i - 1)) / (5 * i - 1) * (pow(x, 5 * i - 1));
sum += power_n1 / (5 * i - 1) * power_x5;
power_n1 = -power_n1;
power_x5 *= x*x*x*x*x;
}

Replacing if statement C++

I want to realize this simple C++ program:
(if y>0) x=2; else x=10;
but without the use of an if statement or any other statement such as for, while, do while, switch or ?.
Is it possible? I am still wondering about this.
You can try this: x = 2 + (y <= 0) * 8; A boolean expression converted to an integral value is either 0 or 1, which you can use to add optional summands.
Here's another option:
x = 10;
y > 0 && (x=2);
Not really recommended, but it works.

C++ Error "lvalue required as left operand of assignment"

I am new to C++ and I have a problem where i have to transform a pseudocode in C++ / C / Pascal language. The answer at the end of the book written in Pascal.
The problem in my C++ code is that at the line 12, I get the error which can be found in the title. Any idea?
Pascal Code:
var n,x:integer;
begin
n:=0;
repeat
write('x=');read(X);
if x<>0 then
if x mod 5 = 0 then
n:=n+1
else
n:=n-1;
until x=0;
if n=0 then
write('yes')
else
write('no')
end;
My C++ Code:
int main()
{
int x,n;
cin>>x;
while(x>0)
{
if(x>0)
{
if(x%5=0){
n=n+1;
} else {
n=n-1;
}
}
if(n=0){
cout<<"Yes"<<;
} else {
cout<<"No"<<;
}
}
}
You have a simple typo: if(x%5=0){ is an attempt to assign 0 to x % 5 (due to operator precedence modulus is computed before assignment). x % 5 cannot be assigned to (it's not an lvalue) and the compiler is telling you that.
The fix, of course, is to write x % 5 == 0.
You're lucky in this case that the error is picked up at compile-time. Something like if (n = 0) (on line 18) might not be, since x = 0 is an expression with value 0.
Two ways to guard against that:
Ensure that your compiler warnings are as aggressive as you can bear. With gcc, I use -Wall -Wextra, and that combination is enough to catch this common problem.
Some developers will write if (0 == x) since an errant if (0 = x) would be picked up at compile time as an attempt to assign to 0. Personally, I find that obfuscating.
Assignment operator requires lvalue means the left side operand need to be a variable/location that can hold a value.
This is what is meant by the error.
What you need in your if statement is == likely not assignment as mentioned by other answers
You need to use == in conditions (while, if, ...) for equality check in C++.
if(x%5 = 0)
should be
if(x%5 == 0)
"x%5" is not an lvalue in that you can not assign a value to it, hence the error.

assuming signed overflow does not occur in if statement

Why is this warning appearing? It's not really an assumption if I check the bounds. And how to fix?
If num_actions_to_skip is set to 1, instead of 2, the error goes away.
Thanks
error: assuming signed overflow does not occur when assuming that (X - c) <= X is always true [-Werror=strict-overflow]
cc1plus: all warnings being treated as errors
On if (loc >= 0 && loc < action_list.count()) {
const QList<QAction *> &action_list = tool_menu->actions();
static const int num_actions_to_skip = 2;
const int loc = action_list.count() - num_actions_to_skip;
if (loc >= 0 && loc < action_list.count()) {
tool_menu->insertAction(action_list.at(loc),
action);
}
It started with
Q_ASSERT_X(i >= 0 && i < p.size()
at qlist.h:454, which performs the same check, and throws this error as well, with just
tool_menu->insertAction(action_list.at(action_list.count() - 2),
action);
You just need to rethink your logic.
static const int num_actions_to_skip = 2;
const int loc = action_list.count() - num_actions_to_skip;
if (loc >= 0 && loc < action_list.count()) {
// ...
}
Apparently action_list.count() is a constant value (at least it won't change as this code is executed), and the compiler is able to figure that out.
Let's simplify this a bit, replacing num_actions_to_skip by 2, reducing action_list.count() to count. We can then re-express loc as count - 2.
Your if condition becomes:
if (count - 2 >= 0 && count - 2 < count)
which is equivalent (assuming, as the compiler warning said, that no overflow occurs) to:
if (count >= 2 && -2 < 0)
The second half of that, -2 > 0 is obviously true, so you can safely drop it, which leaves us with
if (count >= 2)
Re-substituting the original terms, this gives us:
static const int num_actions_to_skip = 2;
// const int loc = action_list.count() - num_actions_to_skip;
if (action_list.count() >= num_actions_to_skip) {
// ...
}
The compiler warned you that it was performing an optimization that might be invalid if there's an integer overflow (it's permitted to assume that there is no overflow because if there is the behavior is undefined). It was kind enough to warn you about this -- which is lucky for you, because it pointed to the fact that your code is doing something it doesn't need to.
I don't know whether you need to keep the declaration of loc; it depends on whether you use it later. But if you simplify the code in the way I've suggested it should work the same way and be easier to read and understand.
If you get a warning message from the compiler, your goal should not just be to make the message go away; it should be to drill down and figure out just what the compiler is warning you about, and beyond that why your code causes that problem.
You know the context of this code better than I do. If you look at the revised version, you may well find that it expresses the intent more clearly.
From this GCC resource:
-Wstrict-overflow
-Wstrict-overflow=n
This option is only active when -fstrict-overflow is active. It warns about cases where the compiler optimizes based on the assumption that signed overflow does not occur. Note that it does not warn about all cases where the code might overflow: it only warns about cases where the compiler implements some optimization. Thus this warning depends on the optimization level.
An optimization that assumes that signed overflow does not occur is perfectly safe if the values of the variables involved are such that overflow never does, in fact, occur. Therefore this warning can easily give a false positive: a warning about code that is not actually a problem. To help focus on important issues, several warning levels are defined. No warnings are issued for the use of undefined signed overflow when estimating how many iterations a loop requires, in particular when determining whether a loop will be executed at all.
-Wstrict-overflow=1
Warn about cases that are both questionable and easy to avoid. For example, with -fstrict-overflow, the compiler simplifies x + 1 > x to 1. This level of -Wstrict-overflow is enabled by -Wall; higher levels are not, and must be explicitly requested.
-Wstrict-overflow=2
Also warn about other cases where a comparison is simplified to a constant. For example: abs (x) >= 0. This can only be simplified when -fstrict-overflow is in effect, because abs (INT_MIN) overflows to INT_MIN, which is less than zero. -Wstrict-overflow (with no level) is the same as -Wstrict-overflow=2.
-Wstrict-overflow=3
Also warn about other cases where a comparison is simplified. For example: x + 1 > 1 is simplified to x > 0.
-Wstrict-overflow=4
Also warn about other simplifications not covered by the above cases. For example: (x * 10) / 5 is simplified to x * 2.
-Wstrict-overflow=5
Also warn about cases where the compiler reduces the magnitude of a constant involved in a comparison. For example: x + 2 > y is simplified to x + 1 >= y. This is reported only at the highest warning level because this simplification applies to many comparisons, so this warning level gives a very large number of false positives.
The solution was to change my ints to unsigned ints:
const QList<QAction *> &action_list = tool_menu->actions();
static const unsigned int num_actions_to_skip = 2;
const unsigned int pos = action_list.count() - num_actions_to_skip;
assert(pos >= 0);
tool_menu->insertAction(action_list.at(pos),
action);
I just solved a similar issue on a comparison that works fine for x86 but not for arm (optimization level O2):
I replaced (x<right) by (x-right<0) and the code is fine now.
And it sounds logical (on hindsight): The new code is worse to read for humans but expresses what the compiler does even for the overflow case.
static inline bool shape_int_rectangle_contains (
const shape_int_rectangle_t *this_, int32_t x, int32_t y )
{
bool result;
const int32_t right = (*this_).left + (*this_).width;
const int32_t bottom = (*this_).top + (*this_).height;
/*
* warning: assuming signed overflow does not occur when assuming that (X + c) >= X is always true [-Wstrict-overflow]
*
* result = ( x >= (*this_).left )&&( y >= (*this_).top )&&( x < right )&&( y < bottom );
*
* fix:
*/
result = ( x-(*this_).left >= 0 )&&( y-(*this_).top >= 0 )&&( x-right < 0 )&&( y-bottom < 0 );
return result;
}

Return statement that works but doesn't make much sense

I have the following function:
int mult(int y, int z)
{
if (z == 0)
return 0;
else if (z % 2 == 1)
return mult(2 * y, z / 2) + y;
else
return mult(2 * y, z / 2);
}
What I need to do is prove its correctness by induction. Now the trouble I'm having is that even though I know it works since I ran it I can't follow each individual step.
What is confusing me is that y only shows up as an argument and in no place does it show up in a return except in the recursive part, and yet the function actually returns y as the answer.
How does this happen? I need to be able to follow everything that happens so that I can do the iterations of it for the proof.
Since this is obviously a homework question, I recommend you do what the assinment was likely meant fot you to do. Trace through the code.
1) give a starting value for y and z.
2) either on paper or in a debugger, trace what happens when you call the function.
3) repeat step 2 with your current y/z values until program completion.
#include <iostream>
using namespace std;
int mult(int y, int z)
{
if(z==0) {
cout<<"z is null! - y:"<<y<<" z: "<<z<<endl;
return 0;
}
else if (z%2==1)
{
cout<<"z is odd! - y:"<<y<<" z: "<<z<<endl;
// make z even
return mult(2*y,z/2)+y;
}
else
{
cout<<"z is even! - y:"<<y<<" z: "<<z<<endl;
return mult(2*y,z/2);
}
}
int main() {
cout<<"result: "<<mult(3,13)<<endl;
}
Output:
z is odd! - y:3 z: 13
z is even! - y:6 z: 6
z is odd! - y:12 z: 3
z is odd! - y:24 z: 1
z is null! - y:48 z: 0
result: 39
How it works for 3 and 13:
There's a switch for even and odd numbers (see comment in code).
When z is null, the recursion "starts to return to the initial call". If the number z is odd it adds y to the returned value of the recursive call, if it's even it justs returns the value from the recursive call.
odd: return 0 + 24
odd: return 24 + 12
even: return 36
odd: return 36 + 3
step-by-step analisis
final result: 100
mult(10, 10)
{
makes 100
mult(20, 5)
{
makes 100
mult(40, 2) + 20
{
makes 80
mult(80, 1)
{
makes 80
mult(160, 0) + 80
{
return 0;
}
}
}
}
}
Note: If this is homework, tag it as such.
So, we basically got three recursive cases. To make it all clearer, I'd rewrite the C-code into some functional pseudo-code. Replace mult with an intuitive operator sign and figure out descriptive explanations of low-level expressions like (z%2==1).
You'll come up with something like
a ** b =
| b is 0 -> 0
| b is even -> 2a ** (b/2)
| b is odd -> 2a ** (b/2) + a
Do you get the point now?
One approach would be to translate each line into "English". My translation would be something like this:
if z is zero, return zero
if z is odd, return mult(y*2, z/2) + y
if z is even, return mult(y*2, z/2)
The general pattern is to recursively call mult with the first parameter doubling, and the second parameter halving.
Note that here you're calling mult with z/2, but its arguments are integers, so if your function continues to recurse, the 2nd parameter will halve each time until it gets down to 1, and then finally 1/2 which rounds down to 0 - at which point recursion will stop because z==0.
With those clues, you should be able to understand how this algorithm works.
Demonstrations by induction are based on proving that the result is valid for the first value, and that if the principle is correct for a generic value N, it is provable that it holds for N+1.
To simplify, you can start by proving that it works for z in { 0, 1, 2 } which should be trivial with a manual test. Then to demonstrate the induction step, you start with a generic z=N, and prove that if mult( y, N ) is a valid result, then mult( y, N+1 ) is also a valid result in terms of the previous one. Since there are different branches for even and odd numbers, you will have to prove the induction step for both even and odd N numbers.
ya = ya
a = an even number
b = the next odd number (in other words a + 1)
So, if you want the equation above in terms of only even numbers (an 'a') when given an odd number (a 'b') you can do the following:
yb = y(a+1) = y*a + y
Now confuse everyone by writing 'a' as 2*(z/2).
y*a becomes (2*y)*(z/2)
y*b becomes ((2*y)*(z/2))+y
Since 'z' appears in the formula for both even and odd numbers, we want to think that the code is telling us that (2*y)*(z/2) = (2*y)*(z/2) + y which is obviously MADNESS!
The reason is that we have snuck in the fact that z/2 is an integer and so z can never be odd. The compiler will not let us assign z/2 to an integer when z is odd. If we try to make 'z' odd, the integer we will really be using is (z-1)/2 instead of z/2.
To get around this, we have to test to see if z/2 is odd and pick our formula based on that (eg. either ya or yb in terms of 'a').
In mult(y,z) both 'y' and 'z' are both integers. Using the symbols above mult(2*y,b/2) becomes mult(2*y,a/2) because b/2 will be truncated to a/2 by the compiler.
Since we are always going to get an 'a' as a parameter to 'mult', even when we send a 'b', we have to make sure we are only using formulas that require 'a'. So, instead of yb we use ya+1 as described above.
b/2 = a/2 + 1/2 but 1/2 cannot be represented as part of an int.
Not really an answer, but more of a suggestion.
You may want to reduce the recursion call from 2 to one:
int mult(int y, int z)
{
int result = 0;
if (z == 0)
return result;
result = mult(2 * y, z / 2); // Common between "then" and "else"
if ((z % 2) == 1)
{
result += y;
}
return result;
}
This could be simplified once more by observing the rule "one exit point only":
int mult(int y, int z)
{
int result = 0;
if (z != 0)
{
result = mult(2 * y, z / 2); // Common between "then" and "else"
if ((z % 2) == 1)
{
result += y;
}
}
return result;
}
Although many compilers will perform this simplification automatically, debugging is usually easier when the code is simplified. The debugger will match the code when single-stepping.
Sometimes simplifying will add clarity. Also, adding comments will help you figure out what you are doing as well as the next person who reads the code.