3

My problem seems to be very basic but I could not find a solution for it. I need to write a code which helps debugging by reporting the line and location of exception throwing. The problem is that __LINE__ is an int value and I have problem with its conversion into string in the following code where std::string(line) is used:

#pragma once

#include <stdexcept>
#include <cstring>


class CRuntime_error_line: public std::runtime_error
{
public:
    CRuntime_error_line(const char * msg, const char * file,int line)
        :runtime_error(std::string(msg)+" @"+":"+std::string(line)){}
};

#define runtime_error_line(msg) CRuntime_error_line(msg,__FILE__,__LINE__)

Seems std::string(line) cannot convert int to string and other solutions suggested online cannot be implemented inline and I don't know how to call a base constructor in second line!

compiler output:

log.h: In constructor ‘CRuntime_error_line::CRuntime_error_line(const char*, const char*, int)’: log.h:10:124: error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive] CRuntime_error_line(const char * msg, const char * file,int line):runtime_error(std::string(msg)+" @"+":"+std::string(line)){}

(Using g++ and linux environment)

edit:

the macro is supposed to be called this way:

throw runtime_error_line("Invalid somethihng ...!");
barej
  • 1,330
  • 3
  • 25
  • 56

3 Answers3

3

As is suggested by Borgleader std::to_string is your solution. It will also construct a temporary std::string for you, so there's no need to construct a temporary string from msg:

#pragma once

#include <stdexcept>
#include <cstring>
#include <string> // Add this to support std::to_string


class CRuntime_error_line: public std::runtime_error
{
public:
    CRuntime_error_line(const char* msg, const char* file, int line)
        : runtime_error(msg + " @:"s + std::to_string(line)){} // Use std::to_string here
};

#define runtime_error_line(msg) CRuntime_error_line(msg, __FILE__, __LINE__)

Without C++11 you can still do this it's just not as clean:

#pragma once

#include <stdexcept>
#include <cstring>
#include <sstream> // Use to include std::ostringstream    

class CRuntime_error_line: public std::runtime_error
{
public:
    CRuntime_error_line(const char* msg, const char* file, int line)
        : runtime_error(static_cast<std::ostringstream&>(std::ostringstream() << msg << " @:" << line).str()){} // Use std::ostringstream here
};

#define runtime_error_line(msg) CRuntime_error_line(msg, __FILE__, __LINE__)
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • seems g++ compiler does not recognize `std::to_string` for me! – barej Dec 09 '14 at 14:39
  • `log.h: In constructor ‘CRuntime_error_line::CRuntime_error_line(const char*, const char*, int)’: log.h:12:40: error: ‘to_string’ is not a member of ‘std’ : runtime_error(msg + (" @:" + std::to_string(line))){} // Use std::to_string here ` – barej Dec 09 '14 at 14:40
  • 1
    have u added : --std=c++11 ? – gosom Dec 09 '14 at 14:47
  • the code compiles but there is something wrong with the output: `0x401938 @:47`. it is not what i expect to see! – barej Dec 09 '14 at 14:50
  • 1
    Thank you very much, please add ` g++ -std=c++11 -o prog.x prog.cpp ` to the end of your solution for others with the similar problem. – barej Dec 09 '14 at 14:55
1

int this case may be better :

#define STRING_DEFINE1(x) #x
#define STRING_DEFINE(x) STRING_DEFINE1(x)
...
CRuntime_error_line(msg,__FILE__,STRING_DEFINE(__LINE__))
Maxim Akristiniy
  • 2,121
  • 2
  • 15
  • 20
1

The simplest thing I can think of would be to write a to_string yourself:

#include <sstream>

std::string to_string(int i)
{
    std::ostringstream os;
    os << i;
    return os.str();
}

Then call it as others have suggested.

Max Lybbert
  • 19,717
  • 4
  • 46
  • 69