Non-volatile errno

ricaljasan ricaljasan@pacific.net
Sat Oct 25 22:21:00 GMT 2014


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



More information about the Libc-help mailing list