Quiting a program using pure C

K

kimimaro

Is there anymore methods in exiting your program using pure C language
other than return 0?
 
N

Nicolas Pavlidis

kimimaro said:
Is there anymore methods in exiting your program using pure C language
other than return 0?

There is a way:
exit(0);

This function, I think it is deklared in stdlib.h finishes your program,
but be aware of memoryleaks.

Kind regards,
Nicolas
 
R

Ravi Uday

kimimaro said:
Is there anymore methods in exiting your program using pure C language
other than return 0?

you can also have
return EXIT_FAILURE;
return EXIT_SUCCESS;

as defined in <stdlib.h>

- Ravi
 
M

Method Man

Nicolas Pavlidis said:
There is a way:
exit(0);

This function, I think it is deklared in stdlib.h finishes your program,
but be aware of memoryleaks.

Most* OS's free the memory when a program has exited so it's not really a
concern over memory leaks, but rather on programming style.

*All that I know of.
 
M

Michael Mair

kimimaro said:
Is there anymore methods in exiting your program using pure C language
other than return 0?

Yep, #include <stdlib.h> and use exit() and abort() (actually,
don't use abort()...):
Use
exit(0);
exit(EXIT_SUCCESS);
if your program is terminated due to circumstances you think
okay (job done, help message printed, ...) and
exit(EXIT_FAILURE);
if something is definitely not okay.

If you want some things done when exiting your program, have
a look at atexit().

Note: Not all environments where you can run programs clean up
the memory, so you should take care of it before calling exit().


Cheers
Michael
 
P

pete

kimimaro said:
Is there anymore methods in exiting your program using pure C language
other than return 0?

Assuming that "by pure C" you're not making the distiction
between the c language proper and the library:
There's the assert macro in <assert.h>
 
M

Michael Mair

Edmund said:
And don't forget: assert(0);

Note: The assert()-macro, if "called" with an expression evaluating
to zero, prints an error message and calls abort().

-Michael
 
J

Jack Klein

Most* OS's free the memory when a program has exited so it's not really a
concern over memory leaks, but rather on programming style.

*All that I know of.

There have been, and still are, a few that don't, or don't always.

The C standard cannot and does not place any requirements on what a
platform might do before or after the execution of a C program. So
the C standard neither requires nor guarantees that an operating
system is able to clean up memory.
 
R

ranjeet

Michael Mair said:
Note: The assert()-macro, if "called" with an expression evaluating
to zero, prints an error message and calls abort().

NOTE : what I think is that when we call assert
And if it get the agrumnet as NULL then
Its display the message as we see in the case of the Poiters
when it gets the Zero as an argument. then it Returns the 0
(Exit the program)

Is my knowledge about assert is correct ????? help in correcting
If i am wrong.

Regards
Ranjeet.
 
M

Michael Mair

ranjeet said:
NOTE : what I think is that when we call assert
And if it get the agrumnet as NULL then
Its display the message as we see in the case of the Poiters
when it gets the Zero as an argument. then it Returns the 0
(Exit the program)

Is my knowledge about assert is correct ????? help in correcting
If i am wrong.

I am sorry, I do not understand what you want to tell me.
Just have a peek at this implementation of assert as my_assert.
I just whipped it up but it should fulfill the basic requirements
for assert. The first five assertions will fail.
Use MY_NDEBUG instead of NDEBUG for switching my_assert off.
If this does not answer your question/complement your
understanding/whatever feel free to ask again.


Cheers
Michael

-----------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>

#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
# define ASSERT_FUNCTION __func__
#else
# define ASSERT_FUNCTION ((const char *) 0)
#endif

#define STRINGIZE(expr) # expr
#define XSTR(expr) STRINGIZE(expr)

#ifdef MY_NDEBUG
# define my_assert(expr) ((void) (0))
#else
# define my_assert(expr) \
((void) ((expr) ? 0 : \
(fprintf(stderr, "Assertion \"" XSTR(expr) "\" failed in %s, "\
"line %d (function %s).\n", __FILE__, __LINE__, \
ASSERT_FUNCTION ? ASSERT_FUNCTION : "?"),abort(), 0)))
#endif /* MY_NDEBUG */


int main (int argc, char **argv)
{
switch (argc) {
case 0:
fprintf(stdout,"Usage: <program> <assertion>\n"
"\tassertions: 0-9\n");
break;
case 1:
fprintf(stdout,"Usage: %s <assertion>\n"
"\tassertions: 0-5\n", argv[0]);
break;
default:
switch (atoi(argv[1])) {
case 0:
my_assert(0);
case 1:
my_assert(NULL);
case 2:
my_assert(1 == 2);
case 3:
my_assert(argv[argc] != NULL);
case 4:
my_assert(0x2b & ~0x2b);
default:
my_assert(1);
}
fprintf(stdout, "arrived here\n\n");
}

return 0;
}
 
M

Michael Wojcik

NOTE : what I think is that when we call assert

assert is a macro, not a function. It's not called, properly speaking.
It's expanded with argument substitution.
And if it get the agrumnet as NULL then

assert evaluates its argument as an integer expression. NULL is a
macro that evaluates to a null pointer constant. All assert cares
about is the truth value of its argument: assert does nothing if
the argument is non-zero, or if the NDEBUG macro was defined (where
assert.h was included in the current translation unit); otherwise it
writes a message to standard error and calls the abort function.

NULL is not the same thing as zero. NULL will evaluate to false, but
the argument to the assert macro need not be a pointer value.
Its display the message as we see in the case of the Poiters
when it gets the Zero as an argument. then it Returns the 0
(Exit the program)

No, it calls the abort function. It does not return anything.

The abort function will cause the program to terminate unless the
SIGABRT signal is being caught and the signal handler does not
return. Whether this counts as "exit[ing] the program" is debatable;
the program stops running, but not necessarily in the same manner as
if the exit function were called. (For example, output streams may
not be flushed.)

In practice, it's often enough to simply think of assert as "test
this condition and kill the program if it's false". The actual
situation, however, is more complicated, and if you're writing
serious C programs it is probably a good idea to understand it.
 
C

Chris Torek

assert is a macro, not a function. It's not called, properly speaking.
It's expanded with argument substitution.
[Correct]
And if it get the agrumnet as NULL then

assert evaluates its argument as an integer expression. NULL is a
macro that evaluates to a null pointer constant. ...

The implication here -- which is also correct -- is that assert(NULL)
does not have to compile.

This is sort of a bug in C89, and is fixed in C99, where the argument
to assert() has type "bool" (from <stdbool.h>; really _Bool). In
C99, assert(NULL) is a valid invocation that -- if NDEBUG is not
defined -- emits a message and calls abort().
NULL is not the same thing as zero. NULL will evaluate to false, but
the argument to the assert macro need not be a pointer value.

In general, even in C89 implementations, assert(ptr) compiles fine
and does the same thing as it is required to do in C99. But a
careful C89 programmer really should write:

assert(ptr != NULL); /* not just assert(ptr) */

"just in case" the program is ever ported to a C89 compiler that
is particularly picky.

(I think Michael Wojcik knows all of this, but it was not specifically
called out in his article.)
 
D

Dan Pop

In said:
assert is a macro, not a function. It's not called, properly speaking.
It's expanded with argument substitution.
[Correct]
And if it get the agrumnet as NULL then

assert evaluates its argument as an integer expression. NULL is a
macro that evaluates to a null pointer constant. ...

The implication here -- which is also correct -- is that assert(NULL)
does not have to compile.

This is sort of a bug in C89, and is fixed in C99, where the argument
to assert() has type "bool" (from <stdbool.h>; really _Bool).

Nope, in C99 the argument to assert has scalar type.
In C99, assert(NULL) is a valid invocation that -- if NDEBUG is not
defined -- emits a message and calls abort().

You're contradicting yourself: if assert expected a bool argument, passing
it (void *)0 would be far from correct: undefined behaviour.

Dan
 
C

Chris Torek

[Specific to C99]

Nope, in C99 the argument to assert has scalar type.

Since I still have not actually bought the final PDF, I will believe
you; but:
You're contradicting yourself: if assert expected a bool argument, passing
it (void *)0 would be far from correct: undefined behaviour.

I remember discussion (from before the C99 standard was final, I think)
about this. The claim was that:

a) assigning a bool variable from a pointer was allowed;

b) the result of such an assignment was "true" if the pointer
compares unequal to NULL and false if it compares equal -- e.g.:

char *p;
...
bool x = p; /* danger, maybe not actually legal C99 */

would always "mean the same thing" as:

bool x = (p != 0);

and therefore

c) by making assert "look like" a function taking a single "bool",
the rules for ordinary function parameter assignment would make:

p = malloc(N);
assert(p);

valid code (however ill-advised one might be to use assert() here).

If either (or both) of (a) or (b) is false in C99, the reasoning
would fall apart. (The pre-C99 draft I use as a quick searchable
text does not support either of the two claims, but I know that
this draft does not match the final standard, and that some of the
changes include details about "bool"s.)

In any case, I maintain that if you want to assert that some pointer
variable compares unequal to NULL, it is best -- for both correctness
*and* "human factor" reasons, as fuzzy and arguable as the latter
may be -- to write:

assert(ptr != NULL);

and not simply:

assert(ptr);

Of course, I also prefer:

if (ptr != NULL)

so "personal preference bias" might affect my "human factor reasons"
claim. :)
 
D

Daniel Vallstrom

Chris Torek said:
[Specific to C99]

Nope, in C99 the argument to assert has scalar type.

Since I still have not actually bought the final PDF, I will believe
you; but:
You're contradicting yourself: if assert expected a bool argument, passing
it (void *)0 would be far from correct: undefined behaviour.

I remember discussion (from before the C99 standard was final, I think)
about this. The claim was that:

a) assigning a bool variable from a pointer was allowed;

b) the result of such an assignment was "true" if the pointer
compares unequal to NULL and false if it compares equal -- e.g.:

char *p;
...
bool x = p; /* danger, maybe not actually legal C99 */

would always "mean the same thing" as:

bool x = (p != 0);

and therefore

c) by making assert "look like" a function taking a single "bool",
the rules for ordinary function parameter assignment would make:

p = malloc(N);
assert(p);

valid code (however ill-advised one might be to use assert() here).

If either (or both) of (a) or (b) is false in C99, the reasoning
would fall apart. (The pre-C99 draft I use as a quick searchable
text does not support either of the two claims, but I know that
this draft does not match the final standard, and that some of the
changes include details about "bool"s.)

C99 guarantees all of (a)-(c):

"6.3.1.2 Boolean type
When any scalar value is converted to _Bool, the result is 0 if the
value compares equal to 0; otherwise, the result is 1."

(Which is germane to the bool concept and you would expect or hope
it to hold also in C99.)

Still, assert takes a scalar argument also in C99 even though AFAICS it
could just as well have been redefined from C89 to take a bool.


Daniel Vallstrom
 
D

Dan Pop

In said:
Chris Torek said:
[Specific to C99]
... sort of a bug in C89, and is fixed in C99, where the argument
to assert() has type "bool" (from <stdbool.h>; really _Bool).

Nope, in C99 the argument to assert has scalar type.

Since I still have not actually bought the final PDF, I will believe
you; but:
In C99, assert(NULL) is a valid invocation that -- if NDEBUG is not
defined -- emits a message and calls abort().
You're contradicting yourself: if assert expected a bool argument, passing
it (void *)0 would be far from correct: undefined behaviour.

I remember discussion (from before the C99 standard was final, I think)
about this. The claim was that:

a) assigning a bool variable from a pointer was allowed;

b) the result of such an assignment was "true" if the pointer
compares unequal to NULL and false if it compares equal -- e.g.:

char *p;
...
bool x = p; /* danger, maybe not actually legal C99 */

would always "mean the same thing" as:

bool x = (p != 0);

and therefore

c) by making assert "look like" a function taking a single "bool",
the rules for ordinary function parameter assignment would make:

p = malloc(N);
assert(p);

valid code (however ill-advised one might be to use assert() here).

If either (or both) of (a) or (b) is false in C99, the reasoning
would fall apart. (The pre-C99 draft I use as a quick searchable
text does not support either of the two claims, but I know that
this draft does not match the final standard, and that some of the
changes include details about "bool"s.)

C99 guarantees all of (a)-(c):

"6.3.1.2 Boolean type
When any scalar value is converted to _Bool, the result is 0 if the
value compares equal to 0; otherwise, the result is 1."

(Which is germane to the bool concept and you would expect or hope
it to hold also in C99.)

It doesn't make any difference, because assert is a *macro*, not a
function, so the fact that pointers are assignment compatible with bools
is irrelevant to an assert defined as taking a bool parameter.
Still, assert takes a scalar argument also in C99 even though AFAICS it
could just as well have been redefined from C89 to take a bool.

It *was* redefined from C89, where it takes an int expression as its
argument. If you define it as taking a bool, then you *must* pass it a
bool argument and not anything that is assignment compatible with a bool.

The rules that apply to function calls don't apply to library macro
invocations, unless the macro is replacing something that is specified as
a function. But this is not the case of assert, which is explicitly
specified as a macro:

7.2.1.1 The assert macro

Synopsis

1 #include <assert.h>
void assert(scalar expression);

Description

2 The assert macro puts diagnostic tests into programs;

Dan
 
D

Daniel Vallstrom

In <[email protected]> (e-mail address removed) (Daniel Vallstrom) writes:

[snip discussion about assert() having a bool argument]
It doesn't make any difference, because assert is a *macro*, not a
function, so the fact that pointers are assignment compatible with bools
is irrelevant to an assert defined as taking a bool parameter.

Fair enough. However, *if* the type of the argument to assert() was
to be changed to bool/_Bool, one could also imagine the addition to
the standard of a new overreaching clause saying that the argument
to macros is to be casted, where applicable, to the macro argument
type when used. AFAICS that would work? (I'm not suggesting it ought
to be done.) Anyway, it is not bool's fault that it isn't the type
of assert().

It *was* redefined from C89, where it takes an int expression as its
argument. If you define it as taking a bool, then you *must* pass it a
bool argument and not anything that is assignment compatible with a bool.

Ah! I obviously wasn't aware that C89 assert() only took int.
Good to know. (Ack, the number of boolean concepts in C...)


Daniel Vallstrom
 
D

Dan Pop

In said:
[email protected] (Dan Pop) wrote in message news: said:
In <[email protected]> (e-mail address removed) (Daniel Vallstrom) writes:

[snip discussion about assert() having a bool argument]
It doesn't make any difference, because assert is a *macro*, not a
function, so the fact that pointers are assignment compatible with bools
is irrelevant to an assert defined as taking a bool parameter.

Fair enough. However, *if* the type of the argument to assert() was
to be changed to bool/_Bool, one could also imagine the addition to
the standard of a new overreaching clause saying that the argument
to macros is to be casted, where applicable, to the macro argument
type when used.

Macro arguments have no types, in general, which is a damn good thing.
AFAICS that would work?

No extra text is or would be needed. Whenever the specification of a
standard library macro requires an expression of a certain type as the
argument, it doesn't matter how this type is achieved, but no other type
can be used instead.
(I'm not suggesting it ought
to be done.) Anyway, it is not bool's fault that it isn't the type
of assert().

Fortunately, because the vast majority of assert() arguments don't have
bool type even when they are conceptually booleans. Would you like
writing assert((bool)(a == b)) instead of assert(a == b) ?
Ah! I obviously wasn't aware that C89 assert() only took int.

The good question is if there was/is any known C89 implementation where
assert(pointer) doesn't work as intuitively expected by its (mis)user.
To me, it looks like a bug in the C89 specification.

Dan
 

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
474,156
Messages
2,570,878
Members
47,408
Latest member
AlenaRay88

Latest Threads

Top