This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
Re: Non-volatile errno
- From: ricaljasan <ricaljasan at pacific dot net>
- To: Mike Frysinger <vapier at gentoo dot org>
- Cc: libc-help at sourceware dot org
- Date: Sat, 25 Oct 2014 15:22:58 -0700
- Subject: Re: Non-volatile errno
- Authentication-results: sourceware.org; auth=none
- References: <544B3061 dot 9080606 at pacific dot net> <20141025054118 dot GB804 at vapier>
On 10/24/2014 10:41 PM, Mike Frysinger wrote:
> On 24 Oct 2014 22:08, ricaljasan wrote:
>> Chapter Error Reporting, section Checking for Errors defines errno as:
>>
>> @deftypevr {Variable} {volatile int} errno
>>
>> and continues on to say:
>>
>> Since @code{errno} is declared @code{volatile}, it might be changed
>> asynchronously by a signal handler; see @ref{Defining Handlers}.
>>
>> but errno is not declared volatile. On a system built with 2.19:
>>
>> $ find /usr/include -name errno.h | xargs grep 'volatile.*errno'
>> $ find /usr/include -name errno.h | xargs grep 'int errno'
>> /usr/include/errno.h:extern int errno;
>>
>> In the current git:
>> $ find . -name errno.h | xargs grep 'volatile.*errno'
>> $ find . -name errno.h | xargs grep 'int errno'
>> ...
>> ./stdlib/errno.h:extern int errno;
>
> it isn't used though. if you read the file:
> #ifndef errno
> extern int errno;
> #endif
So this is like a "default", and not volatile.
>
> and Linux systems do:
> extern int *__errno_location (void) __THROW __attribute__ ((__const__));
> #define errno (*__errno_location ())
> -mike
>
Unfortunately, I'm at the start of the learning curve, so I'm having a
hard time seeing where the above declaration results in 'volatile'. I
get that errno is aliased to __errno_location (for lack of a better term
- maybe "defined as the value that the dereferenced return value of
__errno_location gives" is more correct), but the right half of the
declaration is a little new to me. I read it as the declaration of the
address of an int returned by a function __errno_location which doesn't
take any arguments and ...what? It throws a constant attribute? Sounds
like a temper-tantrum from hell.
Searching for "C declarations with attributes after the function"
yielded this link:
http://web.mit.edu/rhel-doc/3/rhel-gcc-en-3/function-attributes.html
which makes it sound like the const attribute is the opposite of what I
understood the volatile keyword to mean (largely garnered from
https://en.wikipedia.org/wiki/Volatile_variable). const means the
compiler can reduce/optimize the code, volatile means it shouldn't,
because the value can change between calls, despite what it otherwise
thought.
To reconcile volatility, I thought maybe __THROW was a negation (as in
"throw away the const attribute"), but from what I can see it seems to
be a way of saying a C function won't throw an exception, a C++ function
will, or nothing at all. From misc/sys/cdefs.h:
#ifdef __GNUC__
...
# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
# define __THROW __attribute__ ((__nothrow__ __LEAF))
...
# else
# if defined __cplusplus && __GNUC_PREREQ (2,8)
# define __THROW throw ()
...
# else
# define __THROW
So the fallback declaration of errno is as an int and a Linux system
defines it as a macro which expands to the dereferenced return value of
a function which returns the address of an int (errno, actually, which
seems a bit... recursive; see csu/errno-loc.c), has a const attribute,
and may or may not throw an exception depending on whether this is C or
C++. Linux systems actually appear to only do that conditionally (using
sysdeps/unix/sysv/linux/bits/errno.h, but hppa/alpha/mips/sparc under
linux do similarly):
#ifdef _ERRNO_H
...
# ifndef __ASSEMBLER__
/* Function to get address of global `errno' variable. */
extern int *__errno_location (void) __THROW __attribute__ ((__const__));
# if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value. */
# define errno (*__errno_location ())
The above is done unconditionally in sysdeps/mach/hurd/bits/errno.h.
Beyond that, the only other definitions of errno I see are to
rtld_errno, __libc_errno, and errno in include/errno.h.
I'm still failing to see how the manual is correct in stating errno is
declared volatile. This is about the extent of my sleuthing, as I'm now
wondering if I must be mistaken in my understanding of volatile and
const. As much as I love chasing rabbits down their holes, it's
probably best if I wait for a nudge in the right direction now.
You can see why I've only begun submitting patches for grammar in the
manual. I know I have a lot to learn about glibc (and C, period, which
is what originally drew me to reading the manual). This topic came out
of vetting the prototype definitions in the manual. I have a number of
other things I also need to sift through because the source and manual
don't quite seem to line up, but I need to get a little more acquainted
with the landscape of glibc so I can have more surety in my ability to
follow the mazes of dependencies, declarations, definitions, and
what-have-you.
Thank you for the help,
Rical Jasan