简体   繁体   中英

IF Statement has strange behavior

I've developed a 'custom' cout, so that I can display text to console and also print it to a log file. This cout class is passed a different integer on initialization, with the integer representing the verbosity level of the message. If the current verbosity level is greater then or equal to the verbosity level of the message, the message should print.

The problem is, I have messages printing even when the current verbosity level is too low. I went ahead and debugged it, expecting to find the problem. Instead, I found multiple scenarios where my if statements are not working as expected.

The statement if(ilralevel_passed <= ilralevel_set) will sometimes proceed even if ilralevel_set is LESS then ilralevel_passed. You can see this behavior in the following picture (my apologizes for using Twitpic) http://twitpic.com/1xtx4g/full . Notice how ilralevel_set is equal to zero, and ilralevel_passed is equal to one. Yet, the if statement has returned true and is now moving forward to pass the line to cout.

I've never seen this type of behavior before and I'm not exactly sure how to proceed debugging it. I'm not able to isolate the behavior either -- it only occurs in certain parts of my program. Any suggestions are appreciated as always.

//  Here is an example use of the function:
//  ilra_status << setfill('0') << setw(2) << dispatchtime.tm_sec << endl;
//  ilra_warning << "Dispatch time (seconds): " << mktime(&dispatchtime) << endl;

//  Here is the 'custom' cout function:
    #ifndef ILRA_H_
    #define ILRA_H_

    // System libraries
    #include <iostream>
    #include <ostream>
    #include <sstream>
    #include <iomanip>

    // Definitions
    #define ilra_talk ilra(__FUNCTION__,0)
    #define ilra_update ilra(__FUNCTION__,0)
    #define ilra_error ilra(__FUNCTION__,1)
    #define ilra_warning ilra(__FUNCTION__,2)
    #define ilra_status ilra(__FUNCTION__,3)

    // Statics
    static int ilralevel_set = 0;
    static int ilralevel_passed;

    // Classes
    class ilra
    {
    public:
        // constructor / destructor
        ilra(const std::string &funcName, int toset)
        {
            ilralevel_passed = toset;
        }
        ~ilra(){};

        // enable / disable irla functions
        static void ilra_verbose_level(int toset){
            ilralevel_set = toset;
        }

        // output
        template <class T>
        ilra &operator<<(const T &v)
        {
            if(ilralevel_passed <= ilralevel_set)
                std::cout << v;
            return *this;
        }

        ilra &operator<<(std::ostream&(*f)(std::ostream&))
        {
            if(ilralevel_passed <= ilralevel_set)
                std::cout << *f;
            return *this;
        }

    };  // end of the class

    #endif /* ILRA_H_ */

When you define a static variable outside a class, you're defining a separate variable for each source file into which you include the header -- changing the value in one doesn't affect the value of the variable with the same name in another file.

What you almost certainly want is to have

int ilralevel_set = 0;
int ilralevel_passed;

In one file where you're defining your object, and:

extern int ilralevel_set;
extern int ilralevel_passed;

in the header. Alternatively, it looks like you could move it all inside the class:

class ilra { 
    int passed_level;
    int set_level;
public:
    ilra(int toset) : passed_level(toset), set_level(0) {}

    verbose_level(int toset) { set_level = toset; }
    // ...
};

You should not be defining static variables in a header file like this:

static int ilralevel_set = 0;
static int ilralevel_passed;

I don't know what you think those definitions do, but they probably don't do what you want.

To declare in the class:

struct A {
   static int ilralevel;
};

You then need to define in one .cpp source file:

int A::ilralevel = 0;

Just a guess .. you're getting different copies of your static globals in different compilation units. fx, route.cpp has it's own copy of ilralevel_passed and ilralevel_set , plus an inlined copy of irla::operator<< . Move ilralevel_passed to a member variable of irla , and ilralevel_set to a static const , and see if that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM