Thread: Variadic function

  1. #1
    Registered User
    Join Date
    Feb 2011
    Posts
    144

    Variadic function

    Hi everyone. I'm trying to create a function called 'safeprint' which will always check whether the string to be printed actually made it out to the screen. It should be called like this:

    int result = safeprint ( __FILE__ , __LINE__ , "Blah blah\n", ... ) ;
    if (result < 0 ) // something bad happened

    I am doing this partly to make up for my pedantic error checking habit. The problem is that since printf is a variadic function, my function has to be too. How do I make this code work ?

    Richard

    Code:
    #include <stdio.h>
    #include <string.h>
    
    #include "Error.h"
    
    static const unsigned int StringMax = 100 ;
    
    int safeprint ( const char* file , const unsigned int line , const char* pstring , ... )
    {
    	char buffer [ StringMax ] ;
    	int ilength = snprintf ( buffer , StringMax , pstring , ... ) ;
    	int icharsprinted = printf ( "%s" , buffer ) ;
    	if ( ilength != icharsprinted )
    	{
    		ErrorMessage ( "Couldn't print to screen." , file , line ) ;
    		return -1 ;
    	}
    
    	return 0 ;
    }

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Richard... believe me, no offense is intended by this, but man you are so over the top on this error checking thing. Seriously, this is more than a tad ridiculous...

    Lets say your text doesn't make it to the screen...
    What will be your first clue?
    Could it be that blank spot on the screen?
    If you have no access to the screen, how do you plan to report the error?

    Moreover, all that error checking --that never gets triggered-- does little more than slow your code down.

    To answer your question about variadic functions... Question 15.4

  3. #3
    Registered User
    Join Date
    Feb 2011
    Posts
    144
    Mate, I know I'm over the top. Maybe it's obsessive-compulsive disorder. If there's a potential error that goes unchecked I can't concentrate on anything else until it's checked.

    I'd like to point out, though, that printf goes to stdout and my ErrorMessage() goes to stderr. Indeed, ErrorMessage() could start playing the Toccata and Fugue in D Minor or flash a lightbulb. This is a Wikipedia bot, intended to run unattended at high speed and where unexpected behaviour could cause massive damage.

    Richard

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Richardcavell View Post
    Mate, I know I'm over the top. Maybe it's obsessive-compulsive disorder. If there's a potential error that goes unchecked I can't concentrate on anything else until it's checked.
    Yep, I'd class that as a disorder alright.

    In fact, some of the *worst* programs I've run are the ones that error check every last thing. They are sluggish, annoying with all their constant pop-ups and beeps and generally harder to live with.

    I will agree that some error checking is indeed necessary... "Is this file open?", "Did this time out?", etc. but building wrappers around perfectly safe functions out of sheer paranoia is definately not good. In my experience printf() is 100% reliable, once you have your format string set correctly and the text appears correctly on the screen, it will keep right on working 'til the cows come home...

    I'd like to point out, though, that printf goes to stdout and my ErrorMessage() goes to stderr. Indeed, ErrorMessage() could start playing the Toccata and Fugue in D Minor or flash a lightbulb. This is a Wikipedia bot, intended to run unattended at high speed and where unexpected behaviour could cause massive damage.

    Richard
    Massive damage to what?
    Tell me... how is a printf() that somehow doesn't make it to the screen going to harm Wikipedia's website?

    Really... my friend, you need to give this a whole lot more thought.

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    What if ErrorMessage() fails?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    Registered User
    Join Date
    Feb 2011
    Posts
    144
    If ErrorMessage() fails, it returns -1. My program gracefully shuts down, letting go of all resources it's borrowed so far.

  7. #7
    Registered User
    Join Date
    Feb 2011
    Posts
    144
    Now, as to the variadic function question,

    It doesn't seem possible to do something like:

    Code:
    int safeprint ( char* string , ... ) 
    {
       printf ( string , ... )
    }
    The only way to deal with the different possibilities is to manually step through the input string and printf each item as it comes up. This means that my safeprint function will have to be able to cope with every conceivable format specifier that printf can handle.

    I think it would be easier to have different functions, like :
    Code:
    int safeprint ( char* string ) ;
    int safeprint2s ( char* string1 , char* string2 ) ;
    int safeprintui ( unsigned int i ) ;
    Is that the best idea? (Other than getting treatment for OCD)

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Check out vprintf et al.

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Code:
    int safeprint ( char* string , ... ) 
    {
       va_list va;
    
       va_start(va, string);
       count = vprintf(string, va);
       va_end(va);
       // insert silly error checking here
    }
    Also see vsprintf, vfprintf, vsnprintf, etc.

    As far as OCD, I'd never joke about it. My brother suffers terribly from it.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    Registered User
    Join Date
    Feb 2011
    Posts
    144
    Behold my masterpiece. safeprint () is a special case when there's just a string. safeprintf () works the same as printf ().

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdarg.h>
    
    #include "Error.h"
    
    int safeprint ( const char* file , const unsigned int line , const char* pstring )
    {
    	int ilength = strlen ( pstring ) ;
    	int icharsprinted = printf ( "%s" , pstring ) ; 
    	if ( ilength != icharsprinted )
    	{
    		ErrorMessage ( "Couldn't print to screen." , file , line ) ;
    		return -1 ;
    	}
    
    	return 0 ;
    }
    
    static const unsigned int buffersize = 200 ;
    
    int safeprintf ( const char* file , const unsigned int line , char* formatstring , ... )
    {
    	va_list va ;
    	va_start ( va , formatstring ) ;
    
    	int icharsprinted = vprintf ( formatstring , va ) ;
    	if ( icharsprinted < 0 )
    	{
    		ErrorMessage ( "Couldn't print to screen." , file , line ) ;
    		return -1 ;
    	}
    
    	va_start ( va , formatstring ) ;
    	char buffer [ buffersize ] ;
    	int ilength = vsnprintf ( buffer , buffersize , formatstring , va ) ;
    	if ( ilength < 0 )
    	{
    		ErrorMessage ( "Couldn't print to screen." , file , line ) ;
    		return -1 ;
    	}
    
    	va_end ( va ) ;
    
    	if ( ilength != icharsprinted )
    	{
    		ErrorMessage ( "Couldn't print to screen." , file , line ) ;
    		return -1 ;
    	}
    
    	return 0 ;
    }

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Richardcavell View Post
    Behold my masterpiece. safeprint () is a special case when there's just a string. safeprintf () works the same as printf ().
    That's a silly thing to do. safeprintf will work just fine if there's only a string.

  12. #12
    Registered User
    Join Date
    Feb 2011
    Posts
    144
    Won't it choke if you do:

    safeprintf ( __FILE__ , __LINE__ , "I am now 25% better at programming C." ) ;

    owing to the % in the string?

  13. #13
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Richardcavell View Post
    Won't it choke if you do:

    safeprintf ( __FILE__ , __LINE__ , "I am now 25% better at programming C." ) ;

    owing to the % in the string?
    So will safeprint. My point was that safeprint is useless if you have safeprintf.

  14. #14
    Registered User
    Join Date
    Feb 2011
    Posts
    144
    You sure? I think safeprint is safe for strings that include %s.

    Richard

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Richardcavell View Post
    You sure? I think safeprint is safe for strings that include %s.

    Richard
    Might be a good idea to error trap it for that, just in case...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling C in Visual Studio 2005
    By emanresu in forum C Programming
    Replies: 3
    Last Post: 11-16-2009, 04:25 AM
  2. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  3. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM

Tags for this Thread