Why does g++ optimize out a critical section of the following code? - c++

The following code causes a crash in my program, because
void fractalizeSegment() {
// Assume next != NULL
double deltaX = next->x - x;
double deltaY = next->y - y;
// Add 3 new points labeled a1, a2, a3 from this to next
Point a3(x + 2.0*deltaX/3.0, y + 2.0*deltaY/3.0, next);
double sqr3 = std::sqrt(3.0);
Point a2(x + deltaX/2.0 - sqr3*deltaY/2.0,
y + deltaY/2.0 + sqr3*deltaX/2.0,
&a3);
Point a1(x + deltaX/3.0, y + deltaY/3.0, &a2);
next = &a1;
}
Is somehow optimized to
void fractalizeSegment() {
next = &a1;
}
The method is called on p0 = {x = 0, y = 0, next = 0x7fffffffe100},
which point to p1 = {x = 1, y = 0, next = 0x0}.
By analyzing the program in the debugger I found that when I'm in the method fractalizeSegment:
a1 = {x = 6.9533558075099091e-310, y = 6.9533558075098597e-310, next = 0x7fffffffe190}
In address a1.next there is
a2 = {x = 6.9533558074508189e-310, y = 4.9406564584124654e-324, next = 0x34}.
Trying to deference (*a2.next).next causes a segmentation fault.
Why does g++ optimize my code like this? How can I prevent it?
The current workaround I found was printing out the values of a1, a2, and a3,
this prevented the optimization.

a1 is a local automatic variable that will be destroyed upon returning from the function, so any use of *next after that will be undefined. The compiler thinks that surely you will not use those values so why bother computing them.
You probably want to create a1 in the heap:
next = new Point(x + deltaX/3.0, y + deltaY/3.0, &a2); //no need of a1.
Maybe also a2 and a3 should be dynamically allocated, but that depends on the implementation of Point, that you did not show.
And remember to delete the allocated objects somewhere.

Related

Which is the value of i in this "simple" initialization?

I have a doubt about this code:
int i, x, z = 4, y = 1;
i = x = z += y++;
Which is the value of i? Can we know that value or not?
First of all, have you tested if this compiles at all?
If not, then why?
Unless you write some code that invokes UB, compiler, regarding basic syntax of the language, has most of the answers you'll ever need. Please test it yourself, and if it's still not clear, or behaves weirdly, then it's something worth asking.
In this case, it's valid, so let's go through it.
#include <iostream>
int main() {
int i, x, z = 4, y = 1;
i = x = z += y++;
std::cout << "i=" << i << std::endl;
}
I compiled, ran it, and here's the result:
$ g++ test.cpp -o test
$ ./test
i=5
So, what is actually going on in this line?
i = x = z += y++;
First of all, it's easier to understand when you add parentheses so it's perfectly obvious what is evaluated and when:
i = (x = (z += (y++)));
i is a result of assignment to x;
x is a result of addition assignment to z;
z is a result of z + (y post increment);
You can then work your way backwards through the list, and will arrive at the correct result:
y++ evaluates to simply y, because post increment affects only value of y, not the result of expression itself;
z is then z + y, which is 4 + 1, or 5;
intermediate expression becomes i = x = z; (or, form that's too obvious, i = (x = z);), and that means that i, just like x is 5.
Whatever you do, please don't actually write code like this, while it's easy to deconstruct, it's not something that is easy to understand at a first glance, and that, more often than not, causes confusion.
Can we know that value or not?
Yes.
Which is the value of i?
5
since you add y to i, where their values are 4 (since i gets assigned the value of z, which is 4) and 1 respectively.
y is incremented after z has been initialized. It's incremented in the following statement, as #john commented.
As #LightnessInOrbit commented, this is not good code. Forget about it and move on.
Yes the value of i is 5.
Just trace the code.
y++ post increement i,e first assign the value then increement so Y= 4. Next
z += y shorthand operation i,e.., z= z + y ,initially z=4 so 5 = 4+ 1 so Z=5
x = z i.e, x = 5 Next
i = x i.e, i = 5.

C++ operation overloading for multiple types with variadic template initializer list

Hello i´ve created a simple 2D coordinate class (Point2D) and i want to overload this class with some basic operations ( + - * / ) for some basic types(short,int,double....) so i thought i should use a template. The problem is that i get some strage numbers(i think that these are the max size of the type) as x and y value back so therefore it ignores my e.g addition.
Point2D *p = new Point2D(5, 7) //everything works fine here x=5 y=7
Point2D *p = new Point2D(5, 7) + 10;//x= 1.09 * e^-38 same for y but it want x=15 and y=17
Heres the definition of my operation overloading function :
template<class T>
Point2D Point2D::operator+(initializer_list<T> elementList)
{
for (auto elem : elementList)
{
this->x += elem;
this->y += elem;
}
return Point2D(x,y);
}
The behaviour of
Point2D *p = new Point2D(5, 7) + 10;
is undefined. The right hand side is grouped as (new Point2D(5, 7)) + 10 which is adding 10 lots of sizeof(Point2D) to the Point2D* pointer returned back from new!
You are not allowed to set a pointer to memory you don't own, with the exception of one past the end of an array, or one past the address of a scalar, or nullptr.
You can't add 10 to a pointer like that. One way to fix it would be to simply create Point2D's as a local variable:
Point2D p (5, 7);
Point2D q = p + 10;
q will now equal 15,17
That's assuming you create an operator+ that can take ints - your initializer_list one won't work here (because 10 isn't an initializer_list:
template<class T>
Point2D Point2D::operator+(T e)
{
x += e;
y += e;
return Point2D(x, y);
}

rotating a vector using parametric equation of 3d circle [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm not getting the required output i.e x2,y2,z2 in below code. Here the angle t is in degree, (x2,y2,z2) is the pint of vector face after being rotated and (a2,b2,c2) is the direction cosine of the rotated vector.I used rviz to visualize the rotating vector but its not comming as thought i.e its not rotating.
double xgp[ipgp] = 23, ygp[ipgp] = 45, zgp[ipgp] = 345; int ipgp = 0;
double a2, b2 , c2, a1, b1, c1 = ...
double la = 0.0032;
for(double t=0;t<360;t+=la)
{
double x2 = xgp[ipgp]+a2*cos(t)+a1*sin(t);
double y2 = ygp[ipgp]+b2*cos(t)+b1*sin(t);
double z2 = zgp[ipgp]+c2*cos(t)+c1*sin(t);
a2 = x2-xgp[ipgp]; // vector (xgp,ygp,zgp)->(x2,y2,z2)
b2 = y2-ygp[ipgp];
c2 = z2-zgp[ipgp];
int i = round(sqrt(pow(a2,2)+pow(b2,2)+pow(c2,2)));
std::cout<<i<<std::endl;
}
There are two issues with the code that you posted:
You did not specify how (a1,b1,c1) and (a2,b2,c2) are set. These need to be:
orthogonal to (xgp,ygp,zgp)
orthogonal to each other
unit vectors
In the loop, you reset (a2,b2,c2) to be the rotated unit vector. You can't do that and still maintain orthogonality between (a1,b1,c1) and (a2,b2,c2) for the next step of the loop. This is probably the main reason why your print out of i is not all 1's
The following code does what you intend
#include <iostream>
#include <math.h>
int main() {
double xgp = 23., ygp = 45., zgp = 345.;
// setting (a2,b2,c2) to be orthogonal to (xgp,ygp,zgp) with unit magnitude
double a2 = -45./sqrt(23.*23. + 45.*45.);
double b2 = 23./sqrt(23.*23. + 45.*45.);
double c2 = 0.;
// setting (a1,b1,c1) to be orthogonal to both (a2,b2,c2) and (xgp,ygp,zgp)
// using cross product (xgp,ygp,zgp) X (a2,b2,c2) with unit magnitude
double a1 = -23.*345./sqrt(23.*345.*23.*345. + 45.*345.*45.*345. + (23.*23. + 45.*45.)*(23.*23. + 45.*45.));
double b1 = -45.*345./sqrt(23.*345.*23.*345. + 45.*345.*45.*345. + (23.*23. + 45.*45.)*(23.*23. + 45.*45.));
double c1 = (23.*23. + 45.*45.)/sqrt(23.*345.*23.*345. + 45.*345.*45.*345. + (23.*23. + 45.*45.)*(23.*23. + 45.*45.));
double la = 0.0032;
for(double t=0;t<360;t+=la) {
double x2 = xgp+a2*cos(t)+a1*sin(t);
double y2 = ygp+b2*cos(t)+b1*sin(t);
double z2 = zgp+c2*cos(t)+c1*sin(t);
// cannot overwrite a2, b2, c2; otherwise (a2,b2,c2) is no longer orthogonal to (a1,b1,c1)!
double a3 = x2-xgp; // vector (xgp,ygp,zgp)->(x2,y2,z2)
double b3 = y2-ygp;
double c3 = z2-zgp;
// (a3,b3,c3) is a unit vector!
int i = round(sqrt(pow(a3,2)+pow(b3,2)+pow(c3,2)));
std::cout<<i<<std::endl;
}
return(0)
}
Note that rotating in units of degrees or radians does not matter in terms of your question. However, you should follow #Bob 's advice and make sure you know yourself what units you are intending.
Hope this helps.

What happens when we calculate this-(object of current class)

i have class name DPPoint what happens when we calculate this-(object of DPPoint) in same class and assign value to a variable of type int
If I understand correctly the question is about this:
DPPoint* p1 = new DPPoint;
DPPoint* p2 = new DPPoint;
int k = p1 - p2; // what is k?
That's perfectly valid code. It's called "pointer arithmetic". It will give you distance between p1 and p2 in sizes of DPPoint.
DPPoint array [10];
int k = &array[5] - &array[3]; // k = 2
int n = (int)&array[5] - (int)&array[3]; // n = 2 * sizeof (DPPoint)
(&array[5] == &array[3] + 2); // true
(&array[5] == array + 5); // also true
The pointers don't have to be in the same array. Can be two random addresses in memory (skipping alignment issues for simplicity).

Right Runge Kutta 4th method approach?

I have this runge kutta code. However, one mentioned my approach is wrong. And I couldn't really understand why from him, so anyone here, who could give a hint on why this way is wrong?
Vector3d r = P.GetAcceleration();
Vector3d s = P.GetAcceleration() + 0.5*m_dDeltaT*r;
Vector3d t = P.GetAcceleration() + 0.5*m_dDeltaT*s;
Vector3d u = P.GetAcceleration() + m_dDeltaT*t;
P.Velocity += m_dDeltaT * (r + 2.0 * (s + t) + u) / 6.0);
====EDIT====
Vector3d are storing the coordinates, x, y, z.
The GetAcceleration returns the acceleration for each x, y, and z.
You have some acceleration function
a(p,q) where p=(x,y,z) and q=(vx,vy,vz)
Your order 1 system that can be solved via RK4 is
dotp = q
dotq = a(p,q)
The stages of the RK method involve an offset of the state vector(s)
k1p = q
k1q = a(p,q)
p1 = p + 0.5*dt*k1p
q1 = q + 0.5*dt*k1q
k2p = q1
k2q = a(p1,q1)
p2 = p + 0.5*dt*k2p
q2 = p + 0.5*dt*k2q
k3p = q2
k3q = a(p2,q2)
etc. You can either adjust the state vectors of the point P for each step, saving the original coordinates, or use a temporary copy of P to compute k2, k3, k4.
You haven't defined your methods, but the thing that's jumping out at me is you're mixing your results with your inputs. Since Runge-Kutta is a method for calculating y_(n+1) = y_n + hsum(b_ik_i), I would expect your solution to keep your _n terms on the right, and your (n+1) terms on the left. This is NOT what you're doing. Instead, s(n+1) is dependent on r_(n+1) instead of on r_n, t_(n+1) on s_(n+1), and so on. This smells of an error where you attempted to limit the number of variables being used.
With that in mind, can you indicate the actual intermediate values of the calculations your program generates and compare them with the intended intermediate values?