HELP! - time function problem??

R

Razzel

I created this as a test:
#include <time.h>
main(){
printf(X1: %s\n", putim());
printf(X2: %s\n", putim());
}
putim() {
time_t t;
time(&t);
return(ctime(&t));
}
It works and gives me the time of day and date just like "date" command
in linux.
When I use this in a data collection program where I also use sleep commands
(not encompassing any of the above) I get a segmentation fault at/after
the return.

Admittedly, the compile in both cases produces a warning
"return makes integer from pointer without a cast."
Since this is not effecting the test above why is it or the use of sleep
functions killing me with a seg fault?????

Any suggestions would be helpful
Dan
 
P

pete

Razzel said:
I created this as a test:
#include <time.h>
main(){
printf(X1: %s\n", putim());
printf(X2: %s\n", putim());
}
putim() {
time_t t;
time(&t);
return(ctime(&t));
}
It works

It doesn't even compile.
Nobody cares about the vague impressions
in your memory of the appearence of your code.
Use copy and paste facilities!

After you fix up everything that's obviously wrong with it,
then there's nothing wrong with it.

#include <time.h>
#include <stdio.h>

char *putim(void);

int main(void)
{
printf("X1: %s\n", putim());
printf("X2: %s\n", putim());
return 0;
}

char *putim(void)
{
time_t t;

time(&t);
return ctime(&t);
}
 
R

Robert Gamble

I created this as a test:
#include <time.h>
main(){

int main (void){
printf(X1: %s\n", putim());

printf? That's not in time.h...
You are also missing the opening quote, and some form of indentation.
printf(X2: %s\n", putim());

return 0;
}
putim() {

char * putim (void) {

You should put a prototype before the main function as well, that would
look like this:
char * putim (void);
time_t t;
time(&t);

Whoops, you didn't check the return value of time for success.
return(ctime(&t));

Be aware that ctime will return NULL on failure, you should be checking
for this somewhere.
}
It works

It doesn't even compile.
and gives me the time of day and date just like "date" command
in linux.
When I use this in a data collection program where I also use sleep commands
(not encompassing any of the above) I get a segmentation fault at/after
the return.
Admittedly, the compile in both cases produces a warning
"return makes integer from pointer without a cast."

You are returning a char * from putim but you do not put this in your
function definition so the compiler assumes it will return an int. Since
your return value is a pointer, not an int, you get a warning.
Since this is not effecting the test above why is it or the use of sleep
functions killing me with a seg fault?????

Fix your code, if you still have a problem, post the *smallest*
*complete* *compilable* example that demonstrates the problem. Please
make sure you address the items I mentioned first and copy and paste your
code instead of copying it by hand.

Robert Gamble
 
L

Lawrence Kirby

On Thu, 09 Jun 2005 07:21:28 -0400, Robert Gamble wrote:

....
Be aware that ctime will return NULL on failure, you should be checking
for this somewhere.

In the standard C specification of ctime() and asctime() on which its
return value is based, the return value is a pointer to a string. A null
pointer is not a permissible return value.

Lawrence
 
R

Robert Gamble

Lawrence said:
On Thu, 09 Jun 2005 07:21:28 -0400, Robert Gamble wrote:

...


In the standard C specification of ctime() and asctime() on which its
return value is based, the return value is a pointer to a string. A null
pointer is not a permissible return value.

Which is interesting because, according to the standard, ctime(timer)
is equivalent to asctime(localtime(timer)). localtime can return a
null pointer and , according to the equivalent algorithm provided by
the standard for the asctime implementation, passing a null pointer
would invoke undefined behavior. Is the definition of ctime/asctime
broken or am I missing something here?

Robert Gamble
 
C

CBFalconer

Lawrence said:
On Thu, 09 Jun 2005 07:21:28 -0400, Robert Gamble wrote:

...


In the standard C specification of ctime() and asctime() on which
its return value is based, the return value is a pointer to a
string. A null pointer is not a permissible return value.

It is a static string, which is why you have this guarantee. It is
also why the routines are not thread safe. Since C doesn't have
threads, this doesn't matter in this newsgroup.
 
C

CBFalconer

Robert said:
.... snip ...

Which is interesting because, according to the standard, ctime(timer)
is equivalent to asctime(localtime(timer)). localtime can return a
null pointer and , according to the equivalent algorithm provided by

No it can't. It returns a pointer to a static char array. This
cannot be NULL.
 
K

Keith Thompson

CBFalconer said:
Lawrence Kirby wrote: [...]
In the standard C specification of ctime() and asctime() on which
its return value is based, the return value is a pointer to a
string. A null pointer is not a permissible return value.

It is a static string, which is why you have this guarantee. It is
also why the routines are not thread safe. Since C doesn't have
threads, this doesn't matter in this newsgroup.

Right, but there are cases where it matters, even without the use of
threads. For example, a call to asctime() or ctime() will (not
"might", *will*) clobber the result of a previous call.
 
G

Gordon Burditt

Right, but there are cases where it matters, even without the use of
threads. For example, a call to asctime() or ctime() will (not
"might", *will*) clobber the result of a previous call.

Where in ANSI C does it guarantee that the result of a previous
call *MUST* be clobbered?

I have seen the technique used where a function returns a pointer
to a static buffer to rotate between N buffers, so you can use up
to the last N of them (often in the same printf() call) without
fear of their being clobbered. How does this, applied to ctime(),
violate ANSI C? It *still* doesn't make it thread safe.

Gordon L. Burditt
 
K

Keith Thompson

Where in ANSI C does it guarantee that the result of a previous
call *MUST* be clobbered?

I have seen the technique used where a function returns a pointer
to a static buffer to rotate between N buffers, so you can use up
to the last N of them (often in the same printf() call) without
fear of their being clobbered. How does this, applied to ctime(),
violate ANSI C? It *still* doesn't make it thread safe.

C99 7.23.3.1 says:

The asctime function converts the broken-down time in the
structure pointed to by timeptr into a string in the form

Sun Sep 16 01:03:52 1973\n\0

using the equivalent of the following algorithm.

followed by a C implementation of the function. That implementation
uses a single static buffer. An implementation that uses multiple
buffers to avoid clobbering previous results, though it might be a
functional improvement, would not be equivalent to the algorithm
specified by the standard.

C99 7.23.3.2 says that ctime(timer) is equivalent to
asctime(localtime(timer)), so they effectively share the same static
buffer.

Specifying the algorithm this tightly strikes me as a poor choice. On
the other hand, an English specification of the algorithm would have
been verbose and error-prone, so perhaps this was the best tradeoff.
 
R

Robert Gamble

CBFalconer said:
No it can't. It returns a pointer to a static char array. This
cannot be NULL.

7.23.3.4p3:
"The localtime function returns a pointer to the broken-down time, or a
null pointer if the specified time cannot be converted to local time."

Robert Gamble
 
C

CBFalconer

Robert said:
7.23.3.4p3:
"The localtime function returns a pointer to the broken-down time, or a
null pointer if the specified time cannot be converted to local time."

So what? The subject is asctime and ctime. Note the static
declaration of result, and the fact that result is returned. It
can never be NULL. What asctime does if localtime returns NULL is
another matter and up to the implementor. He still has to return
result.
From N869:

[#2] The asctime function converts the broken-down time in
the structure pointed to by timeptr into a string in the
form
Sun Sep 16 01:03:52 1973\n\0

using the equivalent of the following algorithm.

char *asctime(const struct tm *timeptr)
{
static const char wday_name[7][3] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char mon_name[12][3] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static char result[26];

sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
wday_name[timeptr->tm_wday],
mon_name[timeptr->tm_mon],
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec,
1900 + timeptr->tm_year);
return result;
}

[#3] The asctime function returns a pointer to the string.
7.23.3.2 The ctime function

Synopsis

[#1]
#include <time.h>
char *ctime(const time_t *timer);

Description

[#2] The ctime function converts the calendar time pointed
to by timer to local time in the form of a string. It is
equivalent to

asctime(localtime(timer))

Returns

[#3] The ctime function returns the pointer returned by the
asctime function with that broken-down time as argument.

Forward references: the localtime function (7.23.3.4).
 
G

glen herrmannsfeldt

Keith Thompson wrote:

(snip)
Right, but there are cases where it matters, even without the use of
threads. For example, a call to asctime() or ctime() will (not
"might", *will*) clobber the result of a previous call.

I once wanted to print out the creation, modification, and last
access times for a file. My first try used only one printf().

-- glen
 
K

Keith Thompson

CBFalconer said:
No it can't. It returns a pointer to a static char array. This
cannot be NULL.

You didn't quote the entire paragraph:
Which is interesting because, according to the standard, ctime(timer)
is equivalent to asctime(localtime(timer)). localtime can return a
null pointer and , according to the equivalent algorithm provided by
the standard for the asctime implementation, passing a null pointer
would invoke undefined behavior. Is the definition of ctime/asctime
broken or am I missing something here?

Robert Gamble is correct: localtime can return a null pointer. He's
also correct that, given the specified algorithm for asctime(), it
invokes undefined behavior if its argument is a null pointer.

There are no circumstances in which ctime() is required to return a
null pointer, but it can if localtime() returns a null pointer
(returning a null pointer being a possible manifestation of undefined
behavior).
 
R

Robert Gamble

CBFalconer said:
So what? The subject is asctime and ctime. Note the static
declaration of result, and the fact that result is returned. It
can never be NULL. What asctime does if localtime returns NULL is
another matter and up to the implementor. He still has to return
result.
From the quote you responded to, it appeared you were indicating that
localtime could not return a null pointer, if you were going for
something else you should clarify.

The localtime function is important here because the standard states
that a call to ctime(timer) is equivalent to the call
asctime(localtime(timer)) which means that it should behave in the same
manner. The problem is that this manner may invoke undefined behavior,
the way I see it.

I think that you have missed the point of my response to Lawrence
Kirby. I acknowledge the fact that the standard does not seem to allow
ctime/asctime to return a null pointer. The issue I am raising and
looking for enlightenment on is what appears to be the possibility of
invoking undefined behavior during a legal call to ctime.

Here is my logic:

1. A call to ctime(time) is equivalent to asctime(localtime(time))
[7.23.3.2p2]

2. The localtime function can return a null pointer [7.23.3.4p2]

3. The standard specifies the algorithm by which implementations of
asctime must follow [7.23.3.1p2]

4. In this algorithm, the reception of a null pointer leads to
undefined behavior because the parameters to the sprintf statement
attempt to dereference the null pointer provided.

5. The call asctime(localtime(timer)) will cause undefined behavior if
localtime returns a null pointer.

Conclusion: Because of the equivalence subclause, any call to the
Standard function ctime may invoke undefined behavior.

Do you follow? Do you agree?
From N869:

[#2] The asctime function converts the broken-down time in
the structure pointed to by timeptr into a string in the
form
Sun Sep 16 01:03:52 1973\n\0

using the equivalent of the following algorithm.

char *asctime(const struct tm *timeptr)
{
static const char wday_name[7][3] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
static const char mon_name[12][3] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static char result[26];

sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
wday_name[timeptr->tm_wday],
mon_name[timeptr->tm_mon],
timeptr->tm_mday, timeptr->tm_hour,
timeptr->tm_min, timeptr->tm_sec,
1900 + timeptr->tm_year);
return result;
}

[#3] The asctime function returns a pointer to the string.
7.23.3.2 The ctime function

Synopsis

[#1]
#include <time.h>
char *ctime(const time_t *timer);

Description

[#2] The ctime function converts the calendar time pointed
to by timer to local time in the form of a string. It is
equivalent to

asctime(localtime(timer))

Returns

[#3] The ctime function returns the pointer returned by the
asctime function with that broken-down time as argument.

Forward references: the localtime function (7.23.3.4).

Robert Gamble
 
G

Gordon Burditt

Right, but there are cases where it matters, even without the use of
I once wanted to print out the creation, modification, and last
access times for a file. My first try used only one printf().

Oops! I suspect a lot of people have done that.

There are few systems that actually keep a "creation time" (so
printing one is difficult) in spite of a typo in some manual pages.
TRSDOS did, for one. FreeBSD 5.* does but only on UFS2 filesystems.
What you get on UNIX with "ls -lct" isn't a creation time.

Gordon L. Burditt
 
C

CBFalconer

Robert said:
.... snip ...

Here is my logic:

1. A call to ctime(time) is equivalent to asctime(localtime(time))
[7.23.3.2p2]

2. The localtime function can return a null pointer [7.23.3.4p2]

3. The standard specifies the algorithm by which implementations of
asctime must follow [7.23.3.1p2]

4. In this algorithm, the reception of a null pointer leads to
undefined behavior because the parameters to the sprintf statement
attempt to dereference the null pointer provided.

5. The call asctime(localtime(timer)) will cause undefined behavior if
localtime returns a null pointer.

Conclusion: Because of the equivalence subclause, any call to the
Standard function ctime may invoke undefined behavior.

Do you follow? Do you agree?

I guess I have to. It points out a defect in the standard, IMO.
 
K

Keith Thompson

CBFalconer said:
Robert said:
... snip ...

Here is my logic:

1. A call to ctime(time) is equivalent to asctime(localtime(time))
[7.23.3.2p2]

2. The localtime function can return a null pointer [7.23.3.4p2]

3. The standard specifies the algorithm by which implementations of
asctime must follow [7.23.3.1p2]

4. In this algorithm, the reception of a null pointer leads to
undefined behavior because the parameters to the sprintf statement
attempt to dereference the null pointer provided.

5. The call asctime(localtime(timer)) will cause undefined behavior if
localtime returns a null pointer.

Conclusion: Because of the equivalence subclause, any call to the
Standard function ctime may invoke undefined behavior.

Do you follow? Do you agree?

I guess I have to. It points out a defect in the standard, IMO.

I don't see that it's necessarily a defect. ctime() invokes undefined
behavior only if localtime() returns a null pointer, which can happen
only if the argument cannot be converted to local time. It's not the
worst instance of poor error checking in <time.h>.

I suppose it would be good if the specified algorithm for asctime()
handled null pointers more gracefully, say by returning a null
pointer.
 
R

Robert Gamble

CBFalconer said:
Robert said:
... snip ...

Here is my logic:

1. A call to ctime(time) is equivalent to asctime(localtime(time))
[7.23.3.2p2]

2. The localtime function can return a null pointer [7.23.3.4p2]

3. The standard specifies the algorithm by which implementations of
asctime must follow [7.23.3.1p2]

4. In this algorithm, the reception of a null pointer leads to
undefined behavior because the parameters to the sprintf statement
attempt to dereference the null pointer provided.

5. The call asctime(localtime(timer)) will cause undefined behavior if
localtime returns a null pointer.

Conclusion: Because of the equivalence subclause, any call to the
Standard function ctime may invoke undefined behavior.

Do you follow? Do you agree?

I guess I have to. It points out a defect in the standard, IMO.

I don't see that it's necessarily a defect. ctime() invokes undefined
behavior only if localtime() returns a null pointer, which can happen
only if the argument cannot be converted to local time. It's not the
worst instance of poor error checking in <time.h>.

But what exactly constitutes "cannot be converted to local time"? If the
system time service is currently unavailable and the information needed to
make the conversion cannot be established, localtime could conceivably
return a null pointer. This may be very unlikely but still well within
the realm of possibility. The problem then becomes the fact that you
cannot call ctime while guaranteing that undefined behavior
won't result. This should be considered as a defect and addressed,
otherwise it might as well join the ranks of gets() as it's not much safer.
I suppose it would be good if the specified algorithm for asctime()
handled null pointers more gracefully, say by returning a null
pointer.

This is exactly what happens on my system (which at the time of my
original posting I believed to be Standard behavior), the Standard should
probably adopt a similiar behavior.

Robert Gamble
 
K

Keith Thompson

Robert Gamble said:
This is exactly what happens on my system (which at the time of my
original posting I believed to be Standard behavior), the Standard should
probably adopt a similiar behavior.

If we're going to fix the asctime() algorithm, I have a bunch of
suggestions. I suspect the general intent is that it should be
superseded by strftime(), though.

The whole <time.h> interface is badly in need of a redesign. (A
number of people have tried, but nobody has yet succeeded in getting a
new design into the standard.) Of course the existing interface has
to be kept to avoid breaking old programs; at best, it might be made a
little more robust.
 

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

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top