Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I replace my c++ exception macro with an inline function with __LINE__ and __FILE__ support?

I currently read the book Effective C++ from Scott Meyers. It says I should prefer inline functions over #define for function-like macros.

Now I try to code an inline function to replace my exception macro. My old macro looks like this:

#define __EXCEPTION(aMessage) \
{ \
    std::ostringstream stream; \
    stream << "EXCEPTION: " << aMessage << ", file " <<__FILE__ << " line " << __LINE__; \
    throw ExceptionImpl(stream.str()); \
}

My new inline function is this:

inline void __EXCEPTION(const std::string aMessage)
{
   std::ostringstream stream;
   stream << "EXCEPTION: " << aMessage << ", file " <<__FILE__ << " line " << __LINE__;
   throw ExceptionImpl(stream.str());
}

As probably some people already expect, now the __FILE__ and __LINE__ macros are useless, because they refer always to the C++-file with the definition of the inline function.

Is there any way to circumvent this behaviour or should I stick with my old macro? I read this threads here, and I already suspect that there is probably no way of my second example to work fine:

  • Behavior of __LINE__ in inline functions
  • __FILE__, __LINE__, and __FUNCTION__ usage in C++
like image 949
John Avatar asked Feb 05 '15 07:02

John


People also ask

What is __ LINE __ in C?

__LINE__ is a preprocessor macro that expands to current line number in the source file, as an integer. __LINE__ is useful when generating log statements, error messages intended for programmers, when throwing exceptions, or when writing debugging code.

What is __ file __ in C?

__FILE__ This macro expands to the name of the current input file, in the form of a C string constant. This is the path by which the preprocessor opened the file, not the short name specified in ' #include ' or as the input file name argument. For example, "/usr/local/include/myheader.

What is __ function __ in C++?

(C++11) The predefined identifier __func__ is implicitly defined as a string that contains the unqualified and unadorned name of the enclosing function. __func__ is mandated by the C++ standard and is not a Microsoft extension.

How can you differentiate a macro with an inline function?

An inline function is defined by the inline keyword. Whereas the macros are defined by the #define keyword.


1 Answers

Don't use __ (double underscore) as it's reserved. Having an inline function is better.
However, here you need a mix of macro and the function, hence you can do following:

#define MY_EXCEPTION(aMessage) MyException(aMessage, __FILE__, __LINE__) 

inline void MyException(const std::string aMessage,
                        const char* fileName,
                        const std::size_t lineNumber)
{
   std::ostringstream stream;
   stream << "EXCEPTION: " << aMessage << ", file " << fileName << " line " << lineNumber;
   throw ExceptionImpl(stream.str());
}
like image 128
iammilind Avatar answered Sep 30 '22 16:09

iammilind