Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.
#include<iostream>
#include<string>
using namespace std;

// Generic class for tracing the function call
class functionlogging {
private:
    string name;
    string in{ ">>" };
    string out{ "<<" };
public:
    functionlogging(string x) :name(x) {
        cout << in << name << endl;
    }
    ~functionlogging(){
        cout << out << name << endl;
    }
};

//uses
void generic_function() {
    functionlogging logger{ __func__ };
    int a = 10;
    int b = 100;
    a += b;
}


int main() {
    generic_function();
}

Many times, we do need to log when function call starts and ends for better understanding. With modern C++ concepts like __funct__/RAII, I wrote the small class which can be used to achieve trace. With this I was able to achieve this for above "generic_function()".

Output

>>generic_function
<<generic_function

I wanted others opinion about the functionlogging class and how to make it in such a way that user of this class would have to do the minimal work/code changes in his/her code base.

At present user of this class needs to create a object of this class and pass the __func__ information. Is it acceptable or in a way can it be embed inside something by which user of the class almost do not require to do anything?.

share|improve this question
    
You could use some preprocessor #define like with assert, if you like that more. –  firda 12 hours ago
    
I can't find a meaning for your class, sorry. A debugger just works better. –  black 11 hours ago
1  
@black. That is neither true nor a useful statement. In a data driven program the call history will not be obvious and thus logging is needed to trace where the code has been before a crash point (a lot of that stack information may no longer be available in the core file). Also the comment does not help in any way review the code. –  Loki Astari 11 hours ago
    
@LokiAstari I'm looking for explainations which do help for a code review. Also, your example is questionably related. –  black 11 hours ago

1 Answer 1

up vote 6 down vote accepted

Stop doing this:

using namespace std;

see: Why is “using namespace std;” considered bad practice?

These two are not unique to the class.

string in{ ">>" };
string out{ "<<" };

May as well make them static. Also they re never modified so make them const.

No need to force a flush with std::endl

    cout << in << name << endl;

Prefer "\n" when you don't need a flush (also cerr or clog may be better choices of output stream).

That seems like an overly verbose and error prone way of use.

void generic_function() {
    functionlogging logger{ __func__ };

You have to use up a variable and remember __func__. Can't we get a macro in here to do all the for you? I actually need to look up to see if func is a standard macro.

Just checked the standard:

8.4.1 In general
Paragrah 8:
The function-local predefined variable __func__ is defined as if a definition of the form  

static const char __func__[] = "function-name ";

So I would define the macros:

#define LOG_ENTRY_EXIT_FOR(x)       functionlogging  SomeLongNameThatIsNotLikelyToBeUsedInTheFunctionlogger(x)
#define LOG_ENTRY_EXIT              LOG_ENTRY_EXIT_FOR(__func__)

Then usage is simply:

void generic_function() {
    LOG_ENTRY_EXIT;

    int a = 10;
    int b = 100;
    a += b;
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.