This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: What is errno really defined as


> Errno is declared as a function returning pointer to int and it does not
> modify or read any golbal variables.

No it isn't. You're referring to this line:

> /* Function to get address of global `errno' variable.  */
> extern int *__errno_location (void) __THROW __attribute__ ((__const__));

This line does not declare errno as a function returning pointer to int.
In fact, this line does not define a symbol named errno at all. It declares
a function named '__errno_location' that takes no arguments and returns
a pointer to an integer.

Next, you referred to this line:

> #   define errno (*__errno_location ())

And said:

> What I'm confused by though, is the redefinition of errno as
> (*__errno_location ()), namely, why the extra parentheses, no argument,
> no const attribute, and the return type is * vs int * which, 
> though defalting to int, is considered bad programming practice?

No. This isn't a redefinition. This is the only definition of errno in
that file. It defines 'errno' as the value stored at the address returned
by a call to the function '__errno_location ()' (which, of course, as I
mentioned earlier, is the very same function referred to above).

I'll quote your first line again, because it seems to have a question about
how errno is read or written:

> Errno is declared as a function returning pointer to int and it does not
> modify or read any golbal variables.

The way errno is defined actually makes it quite easy to read and write it
from the application.

If you wrote:

errno = 0;

It would translate to:

(* __errno_location ()) = 0;

i.e. get the address of errno, then write 0 at that address.

If you wrote:

e = errno;

It would translate to:

e = (* __errno_location ());

i.e. read the value at the address of errno into the variable 'e'.

This implementation allows each thread to maintain its own copy of errno.
If errno were a single global variable, this wouldn't have been possible.

> In the file /usr/include/errno.h errno is declared as "extern int errno;"

Again no. It is only declared if not already defined as a macro.

The entire declaration with context is:

#ifndef errno
extern int errno;
#endif

But 'errno' is already defined at this point, because just prior to this,
bits/errno.h (the file you talked about first) is already included and
a macro named 'errno' already is defined.

Regarding the rest of it, you might want to look at csu/errno.c and read
about thread local storage (often shortened as 'TLS'):

https://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Thread_002dLocal.html

> Does anybody really know what errno is?

I hope that my explanation has been somewhat useful.

Cheers,
Arjun


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]