Code from IBM

June 4, 2012 at 3:28 pm | Posted in Uncategorized | Leave a comment

I got the job to fix Segmentation Fault somewhere. While I was searching for strftime(), localtime(), ctime() , localtime_r() etc and their behavior with with multi-threaded programs (POSIX threads), I came across this piece of code from IBM. you can find it here if its still available. I have a screenshot too 🙂

#include <stdio.h>
#include <time.h>
 
int main(void)
{
     char s[100];
     int rc;
     time_t temp;
     struct tm *timeptr;
 
     temp = time(NULL);
     timeptr = localtime(&temp);
 
     rc = strftime(s,sizeof(s),"Today is %A, %b %d.\nTime:  %r", timeptr);
     printf("%d characters written.\n%s\n",rc,s);
 
     return 0;
}
 
/*************************************************
     The output should be similar to:
     46 characters written
     Today is Wednesday, Oct 24.
     Time:  01:01:15 PM
************************************************************/

This C program is not correct. Do you see anything wrong with code ? What is it ? Do you see anything wrong with calls of localtime() and strftime() ? Return values from them are not checked:

  • localtime():
  • Returns NULL when some error occures. You pass this NULL to strftime() and whoaaa.. you got undefined behavior.

  • strftime():
  • Even if localtime() behaved correctly strftime() can return with an error condition. IBM’s code does save return value but again does no check of it. Program is simply printing array passed to strftime() without checking if return value was zero or not. Man page of strftime() says:

The strftime() function returns the number of characters placed in the array, not including the terminating null byte, provided the string, including the terminating null byte, fits. Otherwise, it returns 0, and the contents of the array is undefined. (Thus at least since libc 4.4.4; very old versions of libc, such as libc 4.4.1, would return max if the array was too small.)

Now if the contents of array are undefined then behavior of program is undefined too because you are trying to print an array with undefined contents. It can cause crash (if you are lucky), it can print garbage (you are still lucky) or it can just work fine printing the time because most of the time there will no error and that is utter badluck because definitely it will crash on first run when client is using it (trust me, its very ususal). So what we do ? Just two simple checks and client will be happy and that includes your happiness too. Here is the fixed code:

#include <stdio.h>
#include <time.h>
 
int main(void)
{
     time_t temp;
     struct tm *timeptr;
 
     temp = time(NULL);
     timeptr = localtime(&temp);

     if(NULL == timeptr)
       {
	 printf("Error localtime()\n");
       }
     else
       {
	 int rc;
	 char s[100] = {0}; 
	 rc = strftime(s,sizeof(s),"Today is %A, %b %d.\nTime:  %r", timeptr);
	 if(0 == rc)
	   {
	     printf("Error strftime()\n");
	   }
	 else
	   {
	     printf("%d characters written.\n%s\n",rc,s);
	   }
       }

     return 0;
}
 
/*************************************************
Compiled on Linux:

/home/arnuld/programs/C $ gcc -std=c99 -pedantic -Wall -Wextra ibm.c 
/home/arnuld/programs/C $ ./a.out 
43 characters written.
Today is Monday, Jun 04.
Time:  03:50:57 PM
/home/arnuld/programs/C $ 
************************************************************/

There is one more change. I have put varibales in closest possible block (check out int rc and char s, it is because I don’t see the point of decalring them earlier and using them later. Local variables must be decalred/defined in the closest block possible. Another difference is I am initializing the array with null characters (or filling it with zeroes) so that it does not contain any garbage. This is actually more of a matter of style, a personal thing rather than a rule to write correct programs in C. It does write correct program and its not required that you do same while the first change regarding keeping variables in tightest scope possible definitely comes under one of the methods of writing good C programs.

 


Copyright © 2012 Arnuld Uttre, Village – Patti, P.O – Manakpur, Tehsil – Nangal, Distt. – Ropar, Punjab (INDIA)

Verbatim copying and distribution of this entire article are permitted worldwide, without royalty, in any medium, provided this notice, and the copyright notice, are preserved.

Advertisements

Leave a Comment »

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.
Entries and comments feeds.

%d bloggers like this: