code in time\time.h in glibc-2.7

N

Nickolai Leschov

Hello,

I'm reading code for time function in glibc and I see the following
fragment in file time\time.h:

/* Return the time now, and store it in *TIMER if not NULL. */
time_t
time (timer)
time_t *timer;
{
__set_errno (ENOSYS);

if (timer != NULL)
*timer = (time_t) -1;
return (time_t) -1;
}

How do I read this function declaration?

Nickolai
 
J

James Kuyper

Nickolai said:
Hello,

I'm reading code for time function in glibc and I see the following
fragment in file time\time.h:

/* Return the time now, and store it in *TIMER if not NULL. */
time_t
time (timer)
time_t *timer;
{
__set_errno (ENOSYS);

if (timer != NULL)
*timer = (time_t) -1;
return (time_t) -1;
}

How do I read this function declaration?

This is an non-prototype declaration. Prior to the standardization of C,
this was the only way to declare functions. It is still a permitted way
to do so, though it should be avoided. The above declaration declares
the same interface for time() as the prototype

time_t time(time_t *timer)
{
...

The key difference is that the prototyped declaration causes argument
type checking and automatic argument conversions. With the prototype,
you'll get a diagnostic message if you pass an argument that can't be
implicitly converted to 'time_t *', and if you pass an argument that
isn't time_t*, but is implicitly convertible to time_t* (such as a void*
argument), it will be implicitly converted.

With the non-prototyped declaration, there will be no diagnostic, and no
automatic conversion. In general, passing any argument to time() that
isn't a time_t* will be silently dangerous.
 
K

Keith Thompson

Nickolai Leschov said:
I'm reading code for time function in glibc and I see the following
fragment in file time\time.h:

/* Return the time now, and store it in *TIMER if not NULL. */
time_t
time (timer)
time_t *timer;

This is an old-style (non-prototype) function declaration. Probably
either glibc still caters to ancient C compilers that don't support
prototypes, or you're looking at an old version of glibc. The modern
equivalent would be:

time_t time(time_t *timer)
{
__set_errno (ENOSYS);

This is implementation-specific. Presumably it sets errno to the
value ENOSYS, which presumably indicates that the system doesn't
support asking for the current time. (I don't know why it uses a
macro rather than just assigning a value to errno.)
if (timer != NULL)
*timer = (time_t) -1;
return (time_t) -1;

The time function, for historical reasons, returns its result in two
ways: it returns the result directly, and it stores it via the time_t*
pointer you pass in. You can avoid the latter by passing a null
pointer. This implementation of the time function always returns a
value of -1, which is used to indicate that this functionality is not
supported. (The casts are unnecessary, but if glibc supports ancient
compilers, some of them might need the casts for some reason.)

Presumably this is just the version for systems that don't support
time queries. There must be one or more other versions that return
meaningful values.
}

How do I read this function declaration?

Only the first 3 lines are a function declaration; the whole thing is
a function definition.
 

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
473,773
Messages
2,569,594
Members
45,120
Latest member
ShelaWalli
Top