如何让C/C++预处理器自动还原#line指令至原始行号与文件名?
在C/C++中自动还原#line指令前的原始行号与文件名
C/C++标准本身没有提供让预处理器自动还原之前#line状态的原生指令,但有两种实用方法可以实现类似需求:
方法一:保存原始行号与文件名后手动恢复
预处理器的内置宏__LINE__和__FILE__可以实时获取当前的真实行号和文件名。你只需要在设置自定义#line之前,把这两个宏的值存下来,之后用它们恢复即可,完全跨平台:
// 先把当前真实的行号和文件名存起来 #define ORIGINAL_LINE __LINE__ #define ORIGINAL_FILE __FILE__ // 切换到自定义的行号与文件名 #line 50 "inserted" std::cout << "自定义行:" << __LINE__ << ",文件:" << __FILE__ << std::endl; // 恢复到之前的原始状态 #line ORIGINAL_LINE ORIGINAL_FILE std::cout << "原始行:" << __LINE__ << ",文件:" << __FILE__ << std::endl;
这里ORIGINAL_FILE是字符串常量,预处理器会自动正确解析,不需要额外处理。
方法二:使用编译器特定的#pragma扩展
如果你的代码只针对特定编译器(比如GCC/Clang或MSVC),可以用它们提供的非标准#pragma指令来直接保存和恢复行号状态,写法更简洁:
针对GCC/Clang
// 保存当前行号与文件名状态 #pragma GCC save_line // 切换自定义行号 #line 50 "inserted" std::cout << "自定义行:" << __LINE__ << ",文件:" << __FILE__ << std::endl; // 恢复之前的状态 #pragma GCC restore_line std::cout << "原始行:" << __LINE__ << ",文件:" << __FILE__ << std::endl;
针对MSVC
// 直接推送自定义行号状态,同时保存原始状态 #pragma line(push, "inserted", 50) std::cout << "自定义行:" << __LINE__ << ",文件:" << __FILE__ << std::endl; // 弹出恢复到原始状态 #pragma line(pop) std::cout << "原始行:" << __LINE__ << ",文件:" << __FILE__ << std::endl;
注意:这种方式是编译器扩展,不具备跨平台兼容性,换编译器可能会报错。
内容的提问来源于stack exchange,提问作者waves
相关产品推荐
相关产品推荐

