人们通常可以在 C++ 程序中使用__LINE__
和,其中包含许多工具链,包括 GCC。__FILE__
__LINE__
在 GCC 下计算为类型的表达式int
;
__FILE__
计算为 achar const[N]
其中N是适当的值。
__FILE__
是否有任何主要工具链提供与 with type等价的工具wchar const[N]
?- 如果是这样,它是什么?
您可以自己制作WFILE
:
#define WIDE2(x) L##x
#define WIDE1(x) WIDE2(x)
#define WFILE WIDE1(__FILE__)
用非 ASCII 字符和文件名测试马克.cpp
:
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#define WIDE2(x) L##x
#define WIDE1(x) WIDE2(x)
#define WFILE WIDE1(__FILE__)
int main() {
_setmode(_fileno(stdout), _O_U16TEXT); // required for Unicode output to console
wprintf(L"%s\n", WFILE);
}
Demo(从cmd.exe运行并安装了中文支持):
C:\>cl /W4 /nologo 马克.cpp
马克.cpp
C:\>马克.exe
马克.cpp
利用:
WIDE(MEXPAND(__FILE__))
和
WIDE(STRINGIFY(__LINE__))
或替换__LINE__
为任何需要字符串化的内容,并替换__FILE__
为您想要扩展的任何宏字符串文字。
使用以下定义:
#define STRINGIFY2(m) #m
#define MEXPAND(m) m
#define STRINGIFY(m) STRINGIFY2(m)
#define WIDE(m) L ## m
示例用法:
#define AssertBreakMethod DebugBreak
#define AssertBreakForce(expr) \
do \
{ \
if (!(expr)) \
{ \
OutputDebugStringW(WIDE(MEXPAND(__FILE__)) \
WIDE("(") WIDE(STRINGIFY(__LINE__)) \
WIDE("): Assertion failed: ") \
WIDE(#expr) WIDE("\n")); \
AssertBreakMethod(); \
} \
} \
while (0)
请注意,OutputDebugString 的整个参数在编译时静态组装成单个字符串文字。
宏的字符串化技巧是将它传递给另一个宏。当__FILE__
被传递给MEXPAND
它时,它被扩展。MEXPAND
返回它的参数,现在是一个字符串。然后将领先的 L 放在那里以使其变宽是合法的。
STRINGIFY
做同样的伎俩,它传递它的参数,通过该参数STRINGIFY2
将参数扩展为行号(此时看起来像一个整数),然后STRINGIFY2
将#
符号放在它之前,将整数字符串化。
在 Visual Studio 中,只需用 包围它_T()
,例如:
TRACE( _T("function = %s"), _T(__FUNCTION__);
我会将这个答案作为对较早回复的评论,但由于没有最低 50 的声誉来发表评论,因此不允许...
在 Visual Studio 中,_T(__FILE__)不会扩展为 L__FILE__,除非您在 tchar.h 头文件中修改其 _T 的标准定义。_T(__FILE__) 和 _T(__FUNCTION__) 在 5 年前工作,如果您正在寻找当前文件和函数的广泛版本,今天仍然可以工作。
_T(x) 定义为 __T(x),当定义 _UNICODE 时定义为 L##x,否则定义为 x。因此 _T(__FILE__) 扩展为 __T("my_file.c") 之类的东西,然后根据 _UNICODE 扩展为 L"my_file.c" 或 "my_file.c"。在声称它们不起作用之前测试它们是有用的。
例如使用 constauto name = L"" __FUNCTION__;