Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use the compile time constant __LINE__ in a string?

I can use __LINE__ as a method parameter just fine, but I would like an easy way to use it in a function that uses strings.

For instance say I have this:

11    string myTest()
12    {
13     if(!testCondition)
14       return logError("testcondition failed");
15    }

And I want the result of the function to be:

"myTest line 14: testcondition failed"

How can I write logError? Does it have to be some monstrosity of a macro?

like image 487
Mr. Boy Avatar asked Apr 19 '10 20:04

Mr. Boy


2 Answers

Why do you even need it as a string? What's wrong with an integer? Here are two ways you could write logError():

#define logError(str) fprintf(stderr, "%s line %d: %s\n", __FILE__, __LINE__, str)

// Or, forward to a more powerful function
#define logError(str) logError2(__FILE__, __LINE__, str)
void logError2(const char *file, int line, const char *str);

If you really need the line as a string, you can use the stringizing operator #, but because of the way macros work, you'll need to wrap it in two macros:

#define STRINGIZE(x) STRINGIZE2(x)
#define STRINGIZE2(x) #x
#define LINE_STRING STRINGIZE(__LINE__)

And now LINE_STRING is a macro that will expand to a string containing the current line number wherever it is expanded. If you only had one level of macros (i.e. if you had #define STRINGIZE(x) #x), then you would get the literal string "__LINE__" every time you expanded it, which is not what you want.

like image 155
Adam Rosenfield Avatar answered Oct 30 '22 11:10

Adam Rosenfield


There's no reason to do any run-time work for this:

#include <iostream>

// two macros ensures any macro passed will
// be expanded before being stringified
#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE(x) STRINGIZE_DETAIL(x)

// test
void print(const char* pStr)
{
    std::cout << pStr << std::endl;
}

int main(void)
{
    // adjacent strings are concatenated
    print("This is on line #" STRINGIZE(__LINE__) ".");
}

Or:

#define STOP_HAMMER_TIME(x) #x
#define STRINGIFICATE(x) STOP_HAMMER_TIME(x)

If you're a cool person like James.

like image 42
GManNickG Avatar answered Oct 30 '22 13:10

GManNickG