Thread: C optional function parameter?

  1. #1
    Registered User
    Join Date
    Feb 2006
    Posts
    14

    C optional function parameter?

    Hey guys,

    I am trying to write a function that will have an optional parameter, well maybe you guys can give me a better option. I have a function that will log data (text string, etc.) to a file. I have it reading a file for the debug level 0 means only syslog 1 means debug log. Now in the debug log I need to print out everything, so there are certain things like "Entering functionName()", "Exiting functionName()", etc. that need to be printed only if the debug is set to 1; Otherwise only error are printed to the syslog. This is what I have now:
    Code:
    int logData(char* logMessage, int debugLevel)
    {
        FILE *pFile = NULL;   
        char logMsg[1024];    
        char s[30];
        size_t i;
        struct tm tim;
        time_t now;
        now = time(NULL);     
        tim = *(localtime(&now));
        i = strftime(s,30,"%D %H:%M:%S",&tim);
    
        switch (debugLevel)   
        {
            case 1:
    
                /* Create a new file we can write */
                pFile = fopen(DEBUGFILE, "a+");
                if ( pFile == NULL )
                {
                    syslog(LOG_ERR,"Unable to open DEBUGFILE for reading");
                    return 1; 
                }
    
                fprintf(pFile,"%s [%d] %s\n",s,getpid(),logMessage);
                fclose(pFile); /* Close the file */
                break;
    
            case 0:
            default:
                //Write to var log messages
                syslog(LOG_NOTICE,logMessage);
                break;
       }
       return 0;
    }
    and I call it like so:
    Code:
    if (getDebugLevel(DEBUGGING_LEVEL, value) == 1)
    {
       syslog(LOG_NOTICE, "Unable to get the Debugging Level, assuming 1 (LOGGING TO SYSLOG)");
       return 1;
    }
    
    logData("Entering thisFunction()", debugValue);
    I guess, what I was thinking was adding a specialDebug, and if this was not set, then I would not print, if it was, then I would print to the debug aswell.

    Thanks a ton!

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Make debugLevel a global variable.

    Or if all your debug functions are in the same source file, make it a file scope static variable.

    C doesn't have default or optional parameters.

    Whilst there is the ... notation for variadic functions, there is no way to tell in the called function whether any parameters were passed or not.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I would use assert()-style debugging macros.
    Code:
    #ifndef NDEBUG
    #define debug_str(s) \
        fputs(stderr, s);
    #else
    #define debug_str(s)
    #endif
    That way, when you turn off debugging (by defining NDEBUG), the debugging code isn't even compiled.

    If you wanted more control you could have a macro like DEBUGLEVEL which could be 0 to 3 or something.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Feb 2006
    Posts
    14
    Ok, I see what you guys are saying, heres the thing, this file is sort of like a module, with a bunch on different functions each of which can be called at anytime and anther file will build xml based on the return of the functions. I have a lot of stuff printing so I cannot ifdef it all, I need to somehow call a function, my getDebugLevel() to read the level, which all works fine. The certain "logging lines" need to be printed only in the log file and only if debugLevel is et to 1. I can make it work if I double up, for example:

    Code:
    logData("Querying Mssql server for customer authentication information", debugValue);
    sprintf(sqlbuf, "SELECT * FROM authentication WHERE authentication.id='%s', domain_id);
    logData(sqlbuf, debugValue); ** This should only print to the debug file when debugging in on **
    
    if (dbsqlexec(dbproc) == FAIL)
    {
       sprintf(logMsg, "is_Main_User: RETURNING 1 because could not execute the sql statement: %s", sqlbuf);
       logData(logMsg, debugValue); ** This should only print to the debug file when debugging in on **
    
       syslog(LOG_NOTICE, "is_Main_User: RETURNING 1 because could not execute the sql statement: %s", sqlbuf); ** This should print only to the syslog **
        return 1;
    so here debug is 1 and the first line get printed to the debug log and the second to the sys log.

  5. #5
    pwns nooblars
    Join Date
    Oct 2005
    Location
    Portland, Or
    Posts
    1,094
    If you read what was posted, you would be using a macro for printing your debug information, that way, you don't need to ifdef it all.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    See, the basic idea behind assert() is that you can sprinkle your code with things like
    Code:
    assert(x);
    value = y/x;
    That way, if the assert fails, the program exits, printing a message and the line number and some other information. This is useful for debugging, but you might not want such code in your final progam. It could slow it down, or be impossible. So then you define NDEBUG, and assert() is defined as nothing. It effectively disapears from your code.

    The same principle can be applied to other debugging macros. I often use macros that look like this:
    Code:
    #define debug_str(s) \
        fprintf(stderr, "(" __FILE__ ":%i) %s\n", __LINE__, s)
    #define debugf(s, ...) \
        fprintf(stderr, "(" __FILE__ ":%i) " s "\n", __LINE__, __VA_ARGS__)  /* C99 printf-like macro */
    #define debug_long(x) \
        fprintf(stderr, "(" __FILE__ ":%i) " #x " = %li\n", __LINE__, x)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  3. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. Confusion with * and &
    By Ganoosh in forum C++ Programming
    Replies: 32
    Last Post: 06-23-2005, 10:16 PM