K&R2's implicit declaration of exit() 
Author Message
 K&R2's implicit declaration of exit()

In places, Kernighan & Ritchie 2nd ed. uses exit() without either
#include'ing <stdlib.h> or explicitly declaring the function in their
program source code. This is done in Section 7.6, "Error Handling - Stderr
and Exit", and also in Section 8.3, "Open, Creat, Close, Unlink".

As I understand it, this implicitly causes exit() to be declared as having
return type int, even though exit() really has return type void. This
seems as bad as (and no worse than) the "classic" mistake learners often
make in defining main() with return type void, even though main() must
have return type int.

If I am right, I assume the implicit declaration of exit() with the wrong
return type doesn't matter much, or even at all, on most systems.

Or is there some "let-out" in the C language, to work around or even allow
(apparent) implicit mis-declaration of functions that "traditionally"
required no declaration?

Just curious.

Daniel Barker,
Institute of Cell and Molecular Biology,
Swann Building,
King's Buildings,
Mayfield Road,
Edinburgh
EH9 3JR
UK
--



Tue, 17 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

Quote:

> In places, Kernighan & Ritchie 2nd ed. uses exit() without either
> #include'ing <stdlib.h> or explicitly declaring the function in their
> program source code. This is done in Section 7.6, "Error Handling - Stderr
> and Exit", and also in Section 8.3, "Open, Creat, Close, Unlink".

Note that, besides not using <stdlib.h> (or, at one time it used to be
in <process.h>) for exit, open, creat, close and unlink are not standard
functions. This section is no doubt a reminiscent from times when there
wasn't any ANSI/ISO C standards. Bare in mind that the 2nd ed is based
on the original white book, ANSI information added. Not all of the
non-ANSI stuff was removed, however. If you run this program through an
ANSI-compatible compiler (without non-ANSI errors turned on):

        #include <stdio.h>
        int main(void)
        {
                printf("Hello\n");
                exit(0);
        }

the compiler should give you a warning such as 'exit undefined, assuming
extern returning int'. Since, in the old "prototypeless" world, a
function could be declared as:

        exit();

the compiler won't complain about the argument to it, either. The only
place where you actually had to write the arguments in such a case, was
with variadic functions, for example:

        var_func(int, ...);

Quote:
> As I understand it, this implicitly causes exit() to be declared as having
> return type int, even though exit() really has return type void. This
> seems as bad as (and no worse than) the "classic" mistake learners often
> make in defining main() with return type void, even though main() must
> have return type int.
> If I am right, I assume the implicit declaration of exit() with the wrong
> return type doesn't matter much, or even at all, on most systems.

Not actually. If your program tries to *use* the returned value from
exit, there may be a design problem in the program... As the function of
exit is to exit the program, the return value doesn't matter much. The
program flow should not continue after a call to exit (if you don't
count atexit stuff). Anyway, you have probably run into a situation
where you won't use the return value at all, even if it exists. For
example:

        printf("Hello\n");

By definition, printf returns the number of characters it printed (an
int), but how many of us make use of that information? Perhaps some
don't even know that printf *has* a return value.

Quote:
> Or is there some "let-out" in the C language, to work around or even allow
> (apparent) implicit mis-declaration of functions that "traditionally"
> required no declaration?

Traditionally, the function argument types and return values defaulted
to int. Even the syntax was slightly different. For a function body
example:

        memcmp(m1, m2, len)     /* no dec. needed for retvalue int */
        char    *s1;
        char    *s2;    /* no declaration needed for len, since it's int */
        {
                ...
        }

This changed along with ANSI that borrowed so-called prototypes from
C++, as here:

        int memcmp(char *s1, char *s2, int len)
        {
                ...
        }

(ok, this particular function also uses const and size_t nowadays...)

To support older programs, many compilers still accept the implicit
declarations. In practice, however, don't you use them but use explicit
prototyping. Some compilers have switches you can use to make the
compiler complain about the old use. In the future (when?) I believe
that the implicit declarations will be dropped.

        AriL
--
Humans may send email (if absolutely necessary) to the
obvious non-spam address.
--



Wed, 18 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

Quote:

> In places, Kernighan & Ritchie 2nd ed. uses exit() without either
> #include'ing <stdlib.h> or explicitly declaring the function in their
> program source code. This is done in Section 7.6, "Error Handling - Stderr
> and Exit", and also in Section 8.3, "Open, Creat, Close, Unlink".

> As I understand it, this implicitly causes exit() to be declared as having
> return type int, even though exit() really has return type void. This
> seems as bad as (and no worse than) the "classic" mistake learners often
> make in defining main() with return type void, even though main() must
> have return type int.

I'll let others comment on the legality of not declaring exit.  There is a
fundamental difference exit and main -- I cannot think of a case where the
return value of exit might make a difference, but the return value from main
can be, and is often, used.

--



Wed, 18 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

Quote:
>In places, Kernighan & Ritchie 2nd ed. uses exit() without either
>#include'ing <stdlib.h> or explicitly declaring the function in their
>program source code. This is done in Section 7.6, "Error Handling - Stderr
>and Exit", and also in Section 8.3, "Open, Creat, Close, Unlink".

>As I understand it, this implicitly causes exit() to be declared as having
>return type int, even though exit() really has return type void. This
>seems as bad as (and no worse than) the "classic" mistake learners often
>make in defining main() with return type void, even though main() must
>have return type int.

Indeed.  Both are cases of invoking undefined behaviour.

Quote:
>If I am right, I assume the implicit declaration of exit() with the wrong
>return type doesn't matter much, or even at all, on most systems.

This is true.  Only implementations using a different calling mechanism
for void functions vs int functions are likely to be affected.

Quote:
>Or is there some "let-out" in the C language, to work around or even allow
>(apparent) implicit mis-declaration of functions that "traditionally"
>required no declaration?

No such thing.  The authors of K&R2 have, most likely, simply reused the
code from K&R1, where exit() is an int function (because there are no
void functions in K&R C) and doesn't require an explicit declaration.

Dan
--
Dan Pop
CERN, IT Division

Mail:  CERN - EP, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland
--



Wed, 18 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

Quote:

> In places, Kernighan & Ritchie 2nd ed. uses exit() without either
> #include'ing <stdlib.h> or explicitly declaring the function in their
> program source code. This is done in Section 7.6, "Error Handling - Stderr
> and Exit", and also in Section 8.3, "Open, Creat, Close, Unlink".

> As I understand it, this implicitly causes exit() to be declared as having
> return type int, even though exit() really has return type void. This
> seems as bad as (and no worse than) the "classic" mistake learners often
> make in defining main() with return type void, even though main() must
> have return type int.

> If I am right, I assume the implicit declaration of exit() with the wrong
> return type doesn't matter much, or even at all, on most systems.

> Or is there some "let-out" in the C language, to work around or even allow
> (apparent) implicit mis-declaration of functions that "traditionally"
> required no declaration?

> Just curious.

> Daniel Barker,
> Institute of Cell and Molecular Biology,
> Swann Building,
> King's Buildings,
> Mayfield Road,
> Edinburgh
> EH9 3JR
> UK
> --


In this one case, I would assume that it scarcely matters, since exit()
is guaranteed to *not* return, thus the return value (if any) is
irrelevant.
--



Wed, 18 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

Quote:

>In places, Kernighan & Ritchie 2nd ed. uses exit() without either
>#include'ing <stdlib.h> or explicitly declaring the function in their
>program source code. This is done in Section 7.6, "Error Handling - Stderr
>and Exit", and also in Section 8.3, "Open, Creat, Close, Unlink".
>As I understand it, this implicitly causes exit() to be declared as having
>return type int, even though exit() really has return type void.

Nitpick: exit() doesn't return.  It's hard to imagine an
implementation that cares about its declared return type.
(This doesn't invalidate your question, though.)

--
--Pierre Asselin, Westminster, Colorado

--



Wed, 18 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()


Quote:
> In places, Kernighan & Ritchie 2nd ed. uses exit() without either
> #include'ing <stdlib.h> or explicitly declaring the function in their
> program source code. This is done in Section 7.6, "Error Handling - Stderr
> and Exit", and also in Section 8.3, "Open, Creat, Close, Unlink".

> As I understand it, this implicitly causes exit() to be declared as having
> return type int, even though exit() really has return type void. This

Correct.

Quote:
> seems as bad as (and no worse than) the "classic" mistake learners often
> make in defining main() with return type void, even though main() must
> have return type int.

I don't think so.

Quote:
> If I am right, I assume the implicit declaration of exit() with the wrong
> return type doesn't matter much, or even at all, on most systems.

If the return value is not used (and if I am right) any wrong declaration
of a function's type does not really matter. However, if the value IS
used, a wrong type may cause problems. Then note that the return value of
main usually is used by the startup (and termination) code

And note that I will be wrong when the implementation uses some temporary
storage for the return value which needs to be cleaned up by the caller. I
don't know of any implementations like that though ;-)

For the specific case of exit(), any return value would have no meaning
anyway as it does not ever return.

Greetings from
 _____
 /_|__| Auke Reitsma, Delft, The Netherlands.
/  | \  -------------------------------------
        Remove NO_SPAM_ from my address ...
--



Wed, 18 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

Quote:



>> In places, Kernighan & Ritchie 2nd ed. uses exit() without either
>> #include'ing <stdlib.h> or explicitly declaring the function in their
>> program source code. This is done in Section 7.6, "Error Handling - Stderr
>> and Exit", and also in Section 8.3, "Open, Creat, Close, Unlink".

>> As I understand it, this implicitly causes exit() to be declared as having
>> return type int, even though exit() really has return type void. This

>Correct.

>> seems as bad as (and no worse than) the "classic" mistake learners often
>> make in defining main() with return type void, even though main() must
>> have return type int.

>I don't think so.

     Except for freestanding implementations, main() must return int.

Quote:
>> If I am right, I assume the implicit declaration of exit() with the wrong
>> return type doesn't matter much, or even at all, on most systems.

>If the return value is not used (and if I am right) any wrong declaration
>of a function's type does not really matter. However, if the value IS
>used, a wrong type may cause problems. Then note that the return value of
>main usually is used by the startup (and termination) code

     Possibly, this applies to exit()'s return value as well (unless
someone has chapter and verse on what is to be done w.r.t. to return
codes when exit() is called).

Quote:
>And note that I will be wrong when the implementation uses some temporary
>storage for the return value which needs to be cleaned up by the caller. I
>don't know of any implementations like that though ;-)

     The gotcha stealthily pads through the thick jungle of C code.
It isn't hungry *now*, but when your guard is down, you'll be
irresistably tasty.

Quote:
>For the specific case of exit(), any return value would have no meaning
>anyway as it does not ever return.

     It causes the program to return to the operating system.  Any
value might have context there.

Sincerely,

Gene Wirchenko

Computerese Irregular Verb Conjugation:
     I have preferences.
     You have biases.
     He/She has prejudices.
--



Fri, 20 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

Quote:
>If the return value is not used (and if I am right) any wrong declaration
>of a function's type does not really matter.

You're wrong.  It is a case of undefined behaviour, whether the return
value is used or discarded.  You must be confusing this situation with the
following:

    int foo(){}

It is correct to call foo if you discard its return value, but you invoke
undefined behaviour if you attempt to use the return value, which is
indeterminate.

Calling a function whose declaration is incompatible with its definition
is always and unconditionally undefined behaviour:

    If the function is defined with a type that is not compatible with the
    type (of the expression) pointed to by the expression that denotes the
    called function, the behavior is undefined.

As we all know, int and void are not compatible types.

Dan
--
Dan Pop
CERN, IT Division

Mail:  CERN - EP, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland
--



Fri, 20 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

Quote:

> In this one case, I would assume that it scarcely matters, since exit()
> is guaranteed to *not* return, thus the return value (if any) is
> irrelevant.

It isn't strictly true that it is ok to misdeclare the return value
just because the return value isn't used.

Nothing in the C standard prevents an implementation from having the
following calling conventions:

void foo(int x) ----> x in argument 1 slot on "stack"
int foo(int x)  ----> (int *) pointer to result in slot 1
                      x in slot 2

on such a system, the best you could hope for is that exit() would get
the wrong value.  If it didn't crash first from not having the stack
set up like it expected.

---------------------------------------------------------------------------
Tim Hollebeek                           | "Everything above is a true

URL: http://wfn-shop.princeton.edu/~tim |  false values of true."
--



Fri, 20 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()


Quote:
>     Possibly, this applies to exit()'s return value as well (unless
>someone has chapter and verse on what is to be done w.r.t. to return
>codes when exit() is called).

??? the prototype for exit is:

void exit(int status);

It is that parameter that means main must return an int (it could have
been relaxed to something convertible to an int)

However note that there is very little you could do with the return
value of exit:)

Francis Glassborow      Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Fri, 20 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

:      Possibly, this applies to exit()'s return value as well (unless
: someone has chapter and verse on what is to be done w.r.t. to return
: codes when exit() is called).

: >And note that I will be wrong when the implementation uses some temporary
: >storage for the return value which needs to be cleaned up by the caller. I
: >don't know of any implementations like that though ;-)

:      The gotcha stealthily pads through the thick jungle of C code.
: It isn't hungry *now*, but when your guard is down, you'll be
: irresistably tasty.

        Interestingly enough, in a thread on comp.arch recently,
a subroutine-calling sequence (for a not-quite-hypothetical CPU)
which _would_ run afoul of void/int return mismatch was proposed.
In addition various stack machines through the ages have used
a similar scheme, which consists of reserving a "parameter"
slot on the stack for the return value. Depending on whether
thsi slot was "before" or "after" the PC, all sorts of havoc
could ensue from the mismatch. OK, in the _particular_ case
of exit(), the most likely result would be that the wrong
exit value would be used (because gotten from the wrong stack
offset), but exit may also be confused about its caller's return
address. It's not going to return, but (especially if you are
returning an errror, or it thinks you are) it mighty want to
print a helpful error message indicating where it was called.

        I have to agree with Gene: Don't lie to your compiler.
It will get its revenge later, or one of its relatives will. :-)

        BTW: someone mentioned "in the old days" only declaring
variadic functions. Without naming names, in the not-so-old-days,
a certain major vendor declared _no_ functions that returned
int in the standard headers. Not even variadic functions like
printf(). Yeah, I almost vomitted too...

                                        Mike

--



Fri, 20 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()
Alan L. Folsom, Jr. wrote in a message to Daniel Barker:

 ALFJ> I cannot think of a case where the return value of exit might
 ALFJ> make a difference,

Well, assuming the function my_exit() returns nonzero on success or 0
on failure, something like this could be considered reasonable:

   if (!my_exit())
   {
      some_logging_function("Program was unable to terminate properly!\
n"
                            "Rebooting...");
      if (!system_specific_reboot_function())
      {
          /* panic! */
      }
   }

greetings,
Tom

--



Fri, 20 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

Quote:

>    I have to agree with Gene: Don't lie to your compiler.
> It will get its revenge later, or one of its relatives will. :-)

Well, I never do. But I still think that lying about the type of an unused
return value is less dangerous than lying about a used return value.

Also I'd still like to have references to the proper parts of the standard
w.r.t. this 'problem'. I've looked of course -- but no luck ...

BTW, I of course admit that I was wrong ;-)

Greetings from
 _____
 /_|__| Auke Reitsma, Delft, The Netherlands.
/  | \  -------------------------------------
        Remove NO_SPAM_ from my address ...
--



Tue, 24 Apr 2001 03:00:00 GMT  
 K&R2's implicit declaration of exit()

Quote:



>>     Possibly, this applies to exit()'s return value as well (unless
>>someone has chapter and verse on what is to be done w.r.t. to return
>>codes when exit() is called).

>??? the prototype for exit is:

>void exit(int status);

>It is that parameter that means main must return an int (it could have
>been relaxed to something convertible to an int)

>However note that there is very little you could do with the return
>value of exit:)

     Given a friendly standard, you could use it the same as the
return value from main().  exit() would then be a very quick return to
the OS and the program would have a return code.

Sincerely,

Gene Wirchenko

Computerese Irregular Verb Conjugation:
     I have preferences.
     You have biases.
     He/She has prejudices.
--



Tue, 24 Apr 2001 03:00:00 GMT  
 
 [ 21 post ]  Go to page: [1] [2]

 Relevant Pages 

1. warning: implicit declaration of function 'strerror'

2. 'implicit declaration' question

3. warning: implicit declaration of function `malloc'...why??

4. Help->Can't Compile Ex in pp.140, K&R2

5. K&R1 vs. K&R2

6. "implicit declaration of function printf"

7. How to remove compiler warnings (implicit declaration)

8. implicit declaration

9. implicit declaration of strdup

10. Warning implicit declaration

11. implicit declaration question

12. implicit variable type declaration?

 

 
Powered by phpBB® Forum Software