How to find out if an int has no value

R

Richard

I've really tried searching for this before I thought of bother you guys
with this question. It's such a simple thing, but it's driving me nuts!
Is it possible to check if an int (or any other type) has no value.
something like:

int i;
...
...
...
if (i==NULL){
......
}

I know this doesn't work and I know NULL is a pointer. Is there any way
this can be done?
TIA.
 
J

Joona I Palaste

Richard said:
I've really tried searching for this before I thought of bother you guys
with this question. It's such a simple thing, but it's driving me nuts!
Is it possible to check if an int (or any other type) has no value.
something like:

Scalar types, such as ints, always have values. Therefore your question
does not make sense.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Parthenogenetic procreation in humans will result in the founding of a new
religion."
- John Nordberg
 
R

Richard

Scalar types, such as ints, always have values. Therefore your
question does not make sense.

Okay, than I should be more spesific.
I've got this:

typdef struct
{
int x;
int y;
} Point;

// I now want to make a function that checks if a Point is empty

int pointEmpty(Point p)
{
return (p /*isEmpty*/ ? 1 : 0)
}

How should I do that?
TIA
 
G

Gordon Burditt

I've really tried searching for this before I thought of bother you guys
with this question. It's such a simple thing, but it's driving me nuts!
Is it possible to check if an int (or any other type) has no value.

An int never has "no value". C is not like SQL where integer
variables can have null as well as integer values. A C variable
may have an uninitialized or undefined value, in which case it might
have any value, but this is not distinguishable from a variable
that is assigned that value. It might have some kind of trapping
value, which can't be tested because if you try the program terminates.

Pointers may have a NULL value, which is not the same thing as "no
value".

Gordon L. Burditt
 
N

Nicolas Pavlidis

Richard said:
Okay, than I should be more spesific.
I've got this:

typdef struct
{
int x;
int y;
} Point;

// I now want to make a function that checks if a Point is empty

int pointEmpty(Point p)
{
return (p /*isEmpty*/ ? 1 : 0)
}

How can a point be empty? As said by Joona scalar Types always have
values, but you're responsible that they get initialized correctly.

Or do you want to check if the point is (0,0)?

Kind regards,
Nicolas
 
G

Gordon Burditt

Okay, than I should be more spesific.
I've got this:

typdef struct
{
int x;
int y;
} Point;

// I now want to make a function that checks if a Point is empty

A Point is never empty, unless you add an element to it that
can be used to mark it empty.

typedef struct
{
int x;
int y;
int z;
int isempty;
int isgreen;
} Point;

Now, is it acceptable for a Point to be empty and green at the same
time?

Gordon L. Burditt
 
R

Richard

How can a point be empty? As said by Joona scalar Types always have
values, but you're responsible that they get initialized correctly.

Or do you want to check if the point is (0,0)?

Kind regards,
Nicolas

I want to make a fail save for myself. So, if I'd wrote

Point p;

somewhere without initializing it, I could check it whit my

pointEmpty(p);

function.
I'm beginning to understand that I should be working with extra flags or
something, if I insist in wanthing this. Am I correct?

Kind regards,
Richard
 
R

Richard

(e-mail address removed) (Gordon Burditt) wrote in @library2.airnews.net:
A Point is never empty, unless you add an element to it that
can be used to mark it empty.

typedef struct
{
int x;
int y;
int z;
int isempty;
int isgreen;
} Point;

Now, is it acceptable for a Point to be empty and green at the same
time?

Gordon L. Burditt

I just kind of figured this out myself!
Thanks for replaying.

Regards,
Richard
 
J

Joona I Palaste

I want to make a fail save for myself. So, if I'd wrote
somewhere without initializing it, I could check it whit my

function.
I'm beginning to understand that I should be working with extra flags or
something, if I insist in wanthing this. Am I correct?

Yes you are. C provides no way whatsoever of checking whether a
variable has been initialised. The value of an uninitialised value is
undefined, you can't distinguish it from a value you have initialised.
You must use a separate flag, or always work with initialised values.
 
G

Gordon Burditt

I want to make a fail save for myself. So, if I'd wrote
Point p;

somewhere without initializing it, I could check it whit my

pointEmpty(p);

function.
I'm beginning to understand that I should be working with extra flags or
something, if I insist in wanthing this. Am I correct?

If you forget to initialize a Point, you'll forget to initialize
the flag that says whether it's empty.

Gordon L. Burditt
 
R

Richard

(e-mail address removed) (Gordon Burditt) wrote in @library2.airnews.net:
If you forget to initialize a Point, you'll forget to initialize
the flag that says whether it's empty.

Gordon L. Burditt


That's true, unless the isempty flag has an intial value.
But then I should make a

initPoint(Point p)

function that initiates the point (and sets the isempty flag) and never
write something like

p.x=1;

which is not very elegant.
Or is it?
Is there any other way or should I just drop it?

Regards,
Richard
 
X

xarax

Gordon Burditt said:
An int never has "no value". C is not like SQL where integer
variables can have null as well as integer values. A C variable
may have an uninitialized or undefined value, in which case it might
have any value, but this is not distinguishable from a variable
that is assigned that value. It might have some kind of trapping
value, which can't be tested because if you try the program terminates.

Pointers may have a NULL value, which is not the same thing as "no
value".

And remember that an uninitialized pointer may
have any bit pattern whatsoever. So don't expect
a pointer to have an initial NULL value, unless
you explicitly code the assignment.

--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!
 
G

Gordon Burditt

If you forget to initialize a Point, you'll forget to initialize
That's true, unless the isempty flag has an intial value.

I repeat: if you forget to initialize a Point, you'll also forget
to initialize the flag that says whether it's empty. There's no
way to declare a structure that automatically has one or more
elements initialized. You'll need to (and forget to) do this at
every variable declaration for a Point.
But then I should make a

initPoint(Point p)
If you forget to initialize a Point, you'll forget to call
initPoint(). Oh, yes, you'll forget to check if it's empty
before using it, too.
write something like

p.x=1;

which is not very elegant.

If you forget to initialize a Point, you'll forget NOT to do that.
Or is it?
Is there any other way or should I just drop it?

If you forget to initialize a Point, you'll forget it, so you
won't have to drop it.

There are some uses for having an "unspecified point". However,
trying to cover yourself for forgetting to initialize something
isn't one of them. You'll forget to initialize the flag. You'll
forget to test the flag before using the values. You'll forget
what to do if you encounter an "empty" point where one shouldn't
be empty.

Gordon L. Burditt
 
M

Michael Mair

Cheerio Richard,
Okay, than I should be more spesific.
I've got this:

typdef struct
{
int x;
int y;
} Point;

// I now want to make a function that checks if a Point is empty

int pointEmpty(Point p)
{
return (p /*isEmpty*/ ? 1 : 0)
}

How should I do that?

As the language and its semantics give you no easy way out,
do it yourself:

Either you add another member to your struct to indicate
emptiness, e.g int is_empty.

Or you use x and y themselves:
Your Point members x and y probably are restricted
to a certain range of values; if not, disallow one specific
value, e.g. INT_MIN (from <limits.h>), and set x and y to
this value ASAP after declaring your struct/allocating the memory
for it:

#include <limits.h>
#include <assert.h>

#define NO_GPC_VAL INT_MIN

typedef struct GaussPlaneCoordinate {
int x;
int y;
} GP_Coord;


void Init_GP_Coords (size_t n, GP_Coord *GPC)
{
size_t i;
for (i=0; i<n; i++) {
GPC.x = GPC.y = NO_GPC_VAL;
}
}

int IsEmpty_GP_Coord (GP_Coord *GPC)
{
return ( GPC->x==NO_GPC_VAL && GPC->y==NO_GPC_VAL );
}


int main (void)
{
GP_Coord Point;

Init_GP_Coords(1, &Point);
....


if (IsEmpty_GP_Coord(&Point)) {
/* Do init */
}

assert (!IsEmpty_GP_Coord(&Point));
....

return 0;
}

However, the second method has the disadvantage that you have to
check the range after certain ops.
Why did I choose INT_MIN? If you are using a two's complement
representation, it is often defined as -INT_MAX-1 so you are only
sort of symmetrizing the range.

Disclaimer: I did not check the code, just typed it here to give
you an idea.
Of course, with C99, you might want to use _Bool return type
for IsEmpty_GP_Coord().


HTH
Michael
 
M

Michael Mair

Sorry,

forgot to make another point:

If you want to be sure that points are empty when they start their
life, you should malloc() each and every point and access them
only by pointer; you can do the allocation in a function that
not only malloc()s the memory but also initializes your stuff as
"empty".

In order to get a subtle enough kind of safety, create a typedef'ed
type only for pointers to points. If you don't have the type, you
cannot inadvertently create one uninitialized ;-)


Cheers,
Michael
 
N

Nicolas Pavlidis

Richard said:
berlin.de:
[..]
How can a point be empty? As said by Joona scalar Types always have
values, but you're responsible that they get initialized correctly.

Or do you want to check if the point is (0,0)?
I want to make a fail save for myself. So, if I'd wrote

Point p;

somewhere without initializing it, I could check it whit my

Ok.
IMHO it is good style to write "constructorfunctions", and geting
variables only over this functions. For example:

Point newPoint(int x, int y);

or better:
Point *newPoint(int x, int y);

So you can never get problems with uninitialized values, because you're
simulating a constructor.

With this way also unnecessary extraflags can be avoided.

Kind regards,
Nicolas
 
B

Barry Schwarz

I've really tried searching for this before I thought of bother you guys
with this question. It's such a simple thing, but it's driving me nuts!
Is it possible to check if an int (or any other type) has no value.
something like:

int i;
..
..
..
if (i==NULL){
......
}

I know this doesn't work and I know NULL is a pointer. Is there any way
this can be done?
TIA.

I think you are really asking if it is possible to determine if a
variable has been initialized. Unless you have another variable which
keeps track of such a thing the answer is no. The reason is that the
value stored in an uninitialized variable is indeterminant and any
attempt to evaluate such a value (even simply passing it to a
function) invokes undefined behavior.

Keep in mind that static and file scope variables are always
initialized at the point of definition (either explicitly or by
default) and automatic variables may be initialized at that point or
later by assignment or various functions such as memcpy. Also,
variables allocated by malloc are not initialized while those
allocated by calloc are set to all bits zero which may or may not be a
valid value. Existing variables "relocated" by realloc are unchanged
while new ones created by realloc are not initialized. (Any that are
deallocated by free or realloc don't exist anymore so they don't enter
the discussion.)


<<Remove the del for email>>
 
B

Ben Pfaff

Richard said:
I've got this:

typdef struct
{
int x;
int y;
} Point;

// I now want to make a function that checks if a Point is empty

Based on your later articles I see that you really want to check
whether Point is uninitialized. Well, there's no fail-safe way
to do that, but you can do pretty well by adding a "checksum"
member to the struct, like this:

typedef struct {
int x;
int y;
int checksum;
} Point;

The `checksum' value should depend on `x' and `y' using some kind
of fixed formula, e.g. `checksum = x + y + 555;' The exact
formula isn't too important, but there are a couple of
considerations to keep in mind. First, it should be difficult
for `checksum' to be accidentally correct. That means that, for
example, the case of (x, y, checksum) = (0, 0, 0) should *not* be
valid, and the same goes for other cases where the entire
structure is filled with a single byte value. (This is the
reason for the addition of 555 in my suggested formula.
Otherwise (0, 0, 0) would be valid.) I'm sure you can think of
some other considerations.

Then, whenever you update a Point, update the `checksum' member
as well. Whenever you examine a Point, verify that `checksum' is
correct. When you free a Point, zero `checksum'.

This technique is not entirely fail-safe, of course. First, if
you free a Point without clearing the checksum[*], and then reuse
the same memory later without reinitializing it, it will check
out okay. Second, use of uninitialized values technically
provokes undefined behavior in C. You could get around that by
treating Point and `checksum' as unsigned char arrays, but it's
probably not worth it.

[*] I don't necessary mean via the free() function. There are
other ways to allocate and free objects.
 
B

Ben Pfaff

Michael Mair said:
In order to get a subtle enough kind of safety, create a typedef'ed
type only for pointers to points. If you don't have the type, you
cannot inadvertently create one uninitialized ;-)

A typedef does not create any kind of type safety. If that's not
what you mean, you'll have to elaborate.
 
M

Michael Mair

In order to get a subtle enough kind of safety, create a typedef'ed
A typedef does not create any kind of type safety. If that's not
what you mean, you'll have to elaborate.

Right, reusing the stuff from before:

struct GaussPlaneCoordinate {
....
};

typedef struct GaussPlaneCoordinate *CoP;


My point was that usually people are lazy and will rather use
CoP points = GetGPC(5);
than
struct GaussPlaneCoordinate points[5];
just because of the easyness of the "intended way":

If the intended way to use the coordinates is to get a pointer and
"create" the coordinate it points to by allocating and initializing
it and you have a function doing both, there is a good chance that
someone -- even yourself late in the night -- conveniently forgets
about that. If there is a typedef for "struct GaussPlaneCoordinate",
then it is easier to do so. If there is not, and you have a convenient,
short typedef for "struct GaussPlaneCoordinate *", chances are that
the lazy programmer will go for the typedef'ed type he knows.
(Sounds far-fetched, I know, but I have had an experience quite some
time ago which led me to recode a module and remove all potentially
dangerous typedefs because the people using the stuff for their
applications liked to use, e.g. STRUCT instead of STRUCT *, when
doing something "just quickly", never caring about control words and
the effect when passing the stuff to functions. As it was, it worked
99% of the time and I could not track the misbehavior down to their
code for a long time but checked the stuff I had inherited from
someone else.
When I had removed everything they liked to abuse, the "inexplicable
error" rate went down dramatically, even though they still could
have circumvented it by using the very unhandy names of the original
structures; but as the intended way was now easier to use, they were
too lazy...)


--Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top