如何在字符串中使用编译时常量__LINE__?

Mr.*_*Boy 16 c++ testing c-preprocessor

我可以使用__LINE__方法参数就好了,但我想在一个使用字符串的函数中使用它.

比如说我有这个:

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

我希望函数的结果是:

"myTest第14行:testcondition失败"

我怎么写logError?它是否必须是一个宏观的怪物?

GMa*_*ckG 29

没有理由为此做任何运行时工作:

#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__) ".");
}
Run Code Online (Sandbox Code Playgroud)

要么:

#define STOP_HAMMER_TIME(x) #x
#define STRINGIFICATE(x) STOP_HAMMER_TIME(x)
Run Code Online (Sandbox Code Playgroud)

如果你像詹姆斯一样酷.

  • 或者,如果你鄙视"STRINGIZE"这个词,你可以使用"STRINGIFICATE"并享受同事的奇怪目光. (7认同)
  • @James:Duly注意到了. (2认同)

Ada*_*eld 29

为什么你甚至需要它作为一个字符串?整数有什么问题?您可以通过以下两种方式撰写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);
Run Code Online (Sandbox Code Playgroud)

如果你真的需要行作为字符串,你可以使用字符串化操作符#,但由于宏的工作方式,你需要将它包装在两个宏中:

#define STRINGIZE(x) STRINGIZE2(x)
#define STRINGIZE2(x) #x
#define LINE_STRING STRINGIZE(__LINE__)
Run Code Online (Sandbox Code Playgroud)

现在LINE_STRING是一个宏,它将扩展为包含当前行号的字符串,无论它在哪里展开.如果你只有一个级别的宏(即如果你有#define STRINGIZE(x) #x),那么你"__LINE__"每次扩展它时都会得到文字字符串,这不是你想要的.

  • 虽然这是一个旧线程,但是你希望它作为一个字符串作为你无法使用fprintf()的实例.一个这样的地方在信号处理程序中,因为fprintf()在write()时不能安全地用于信号处理程序. (4认同)

Tim*_*eaf 9

他的目标是创建一个宏(名为logError),它将自动包含必要的符号,并在预处理器中执行字符串连接,仅使用字符串文字.

所以,到目前为止,结合基本正确的答案答案,让我们写宏:

#define STRINGIZE_DETAIL(x) #x
#define STRINGIZE(x) STRINGIZE_DETAIL(x)
#define logError(msg) (__FILE__ " line " STRINGIZE(__LINE__) ": " msg)
Run Code Online (Sandbox Code Playgroud)

然后,您可以在任何位置使用此宏来在编译时以字符串文字格式创建一般错误消息代码.

注意:您也可以使用__FUNCTION__(或等效,它因编译器而异),而不是(__FILE__如果您愿意)跟踪函数名称而不是文件名.