chaosTechnician
chaosTechnician

Reputation: 1700

Can I Access a calling function's name programmatically?

I'm hoping to add a little functionality to a Log File system for a project I'm working on. For my LogError() calls, I would like to include the function the error occurred in. I'm wondering if there's a way that I can access the name of the function that called LogError() so I can programmatically access that information to add it to the log.

For example:

bool Engine::GraphicsManager::Initialize(const HWND i_hWindow_main)
{
    if ( !InitializeWindow( i_hWindow_main ) )
    {
        Engine::LogManager::Instance().LogError(L"GraphicsManager::Initialize - Unable to initialize graphics window");
        return false;
    }
    Engine::LogManager::Instance().LogMessage(L"Graphics window initialized successfully");

    /* SNIP */

    initialized = true;
    return true;
}

In the above example, I'd like LogError() to be able to determine that it was called from GraphicsManager::Initialize() and output (at least part of) that function's name instead of putting that in everywhere by hand.

EDIT: I should have mentioned that my LogError() function (and the other logging functions) are essentially wrappers for vfwprintf_s() so they can take variable length argument lists. While I like the "use a macro" suggestions, I'm not sure how to tackle that potential issue (which is likely another question).

Is this still reasonable/possible?

Thanks!

Upvotes: 3

Views: 2151

Answers (3)

KitsuneYMG
KitsuneYMG

Reputation: 12901

Make a Logging macro

EDIT: Some fixes to deal with wide characters

//support macros
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define STRINGIZE(x) #x
#define __WFILE__ WIDEN(__FILE__)
#define __WFUNCTION__ WIDEN(__FUNCTION__)
#define __WLINE__ WIDEN( STRINGIZE(__LINE__) )
// logging macro
#define LOG(msg) Engine::LogManager::Instance().LogError(__WFILE__ L"::" __WFUNCTION__ L":" __WLINE__ L" - " msg)

Use it like this

if( error ) { LOG(L"Error!"); }

logs

File.cpp::Function:Line - Error!

This works by using C-style string concatenation. "aa" "bb" -> "aabb" along with some operator pasting to put L before "astring". It uses the __FILE__, __FUNCTION__, and __LINE__ macros to report where the error was logged from. __LINE__ is translated into a string with the STRINGIZE macro. Due to crappy compliance with the standard, BOOST_PP_STRINGIZE is recommended if you plan on using boost anyway.

Upvotes: 0

santiagoIT
santiagoIT

Reputation: 9431

These are predefined macros and part of the C/C++ standard which you can use:

__FILE__ __LINE__

They are explained here

Upvotes: 1

Bastien Léonard
Bastien Léonard

Reputation: 61703

You could add an argument for the function name, and pass in the __FUNCTION__ macro: http://msdn.microsoft.com/en-us/library/b0084kay%28v=vs.80%29.aspx

And you could also define a macro that will automatically replace ...log...() with ...log...(__FUNCTION__).

Upvotes: 4

Related Questions