4

I am working with a project in VC++ which involves co-ordinate system having x,y,z axis.
I am trying to check for if a variable(Point with x,y,z values) is assigned on the coordinate system or its a default point(uninitialized) .
Since a coordinate system I cannot assign a default value to the variable to be either negative or positive or even zero since all these are valid values.

My approach over here is to have a Boolean variable associated with my Point variable. If the Boolean is set then Point assigned else not. Now I have to check for each and every statement where the value can be assigned and set the Boolean.

Now I tried with this approach which is pretty bad and you may consider it as wrong. What I am doing here is taking an uninitialized float variable (since x,y,z members of Point are float) and comparing it with x,y,z members of Point variable.
Since in the case where Point is uninitialized both float variable and members of Point match and I can declare its uninitialized. I have tried to test this on different compilers and I get the result as expected.
Obvious I get a compiler warning for uninitialized variable used for comparison

My question, Is the second approach really bad or is there any workarounds over this.

2
  • I would try a different approach: Though all x,y,z values are valid coordinates, I bet that only a subset makes sense in your context. I would use an arbitrary out of context value to specify that a value has not been assigned yet. If all values make sense in your context, you could try to initialize values with special NaN value.
    – mouviciel
    Commented May 5, 2012 at 8:04
  • Not sure if you'd already read my answer, but in case you did, I just want to notify you of the fact that I elaborated a bit :) For the record, I'm not sure if askers are notified of edits or not.
    – Max
    Commented May 6, 2012 at 23:56

5 Answers 5

5

Why not use boost::optional or similar functionality?

boost::optional<point> point;

if(point)
    //is init.

You could make your own template class, but having a separate bool flag is not very good, since it clutters the namespace in every place you want a 'nullable' point. It is also not semantically obvious that the point and the bool are grouped/belong together - especially if multiple people view the code at different points in development etc.

Putting it in the point class is not 100% semantically correct imo - its better to use composition to represent this kind of thing, since a point is a point. If you layer it with a templated 'holder' that groups the bool together with the it is obvious what happens - and other places where you simply need a point, you use the Point as-is.

4

An uninitialised variable always has a value - it's just not going to be a value which is any use to you, instead it'll be a value which has been leftover in memory from the last time that particular chunk of memory had been used. The compiler is warning you that the effect of using an uninitialised variable in a comparison will be undefined, unpredictable behaviour.

if your Point objects need to be able to represent an internal state which indicates whether the coordinates are valid, then your first idea of adding a bool in your Point class would be a more reliable solution. You're going to need to check something so why do you not want to add a bool? Giving your Point class an internal state also lets you validate the state internally, which could be acheived by having a state-getter, or by throwing an exception.

4

Instead of using uninitialized coordinates you could initialize them to NaN (see here) if your compiler supports it.

Then you are always sure whether a point is undefined or it represents a real point in the 3-D space.

7
  • 1
    Comparing with NaN is a hassle.
    – user7043
    Commented May 5, 2012 at 8:43
  • Why is it a hassle? The alternative is to have a boolean flag, and then you have to check that.
    – Giorgio
    Commented May 5, 2012 at 21:09
  • NaN != NaN, a (necessary, I suppose) evil of IEEE floats. Among other things, it means you have to use a special function to detect it (or use the confusing and non-obvious if (val != val)). Also, awry math may result in NaN (e.g. sqrt(-1)), and what should be an error becomes an unintended uninitialized point instead.
    – user7043
    Commented May 5, 2012 at 21:18
  • But if you use a flag you have to check the flag in all the code handling points as well. What is the difference?
    – Giorgio
    Commented May 5, 2012 at 21:20
  • Again, it's less obvious. if (p->initialized) beats if (isNan(p->x)) any day, and promoting NaN to a perfectly normal, expected value in your code means you have to think hard before comparing floating point values everywhere it may leak. Not to mention the possibility of (for instance) x being NaN while y and z aren't -- depending on how the check is done, some code may recognize it while other functions run with it.
    – user7043
    Commented May 5, 2012 at 21:23
2

Is there anything that prevents you from requiring coordinates when initializing the Point? The class might look something like:

class Point {
public:
    Point( float x, float y, float z )
        : _x( x ), _y( y ), _z( z ) {}

    // Getters/setters as needed    

private:
    float _x, _y, _z;
}

At this point, there's no way to create the object without having an initial value, which is presumably valid.

With this approach, if you need uninitialized Point variables somewhere, you will need to use pointers. If you follow the common practice of initializing pointers to NULL (or nullptr), whenever you have a valid pointer to a Point, you have a valid set of coordinates.

1

I regard your second approach really bad.

First, consider whether you can change your design to make instantiation of Point object possible only when valid values for x, y, z coordinates are available. Provide only one constructor that takes all 3 parameters.

Second, consider having a single method of setting coordinates:

void setCoordinates(float x, float y, float z)

In this method, set the state variable that you are using for marking valid values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.