有关宏的使用总结 - 1 (VS编译器)
来源:互联网 发布:身份证找回淘宝账号 编辑:程序博客网 时间:2024/04/29 20:58
11月9日
有关宏的使用总结 - 1 (VS编译器)
今天下午被宏折腾了好久,是时候,该好好总结一下有关于宏的使用了。
1.宏的分段式定义一定要注意,不能在 / 后面有任何的字符,包括空格
例如:
#define PRINTF(s) /
printf(s##"/n");
printf(s##"/n");
如果 #define PRINTF(s) / 这句的后面还有多余的空格,那么vc编译器将提示
error C2017: 非法的转义序列
error C2014: 预处理器命令必须作为第一个非空白空间启动
error C2014: 预处理器命令必须作为第一个非空白空间启动
2.宏的#ifdef #endif格式的定义中,一定要注意#else或#endif之前的那句宏定义,不能加 "/"
例如:
#ifdef _DEBUG
#define PRINTF(s) /
if (s) /
printf(s##"/n"); => 注意这里绝对不能加 "/"
#else
#define PRINTF(s) /
printf(s##"/n"); => 同样这里也绝对不能加 "/"
#endif
#define PRINTF(s) /
if (s) /
printf(s##"/n"); => 注意这里绝对不能加 "/"
#else
#define PRINTF(s) /
printf(s##"/n"); => 同样这里也绝对不能加 "/"
#endif
如果此两处中任意一处加上了"/",编译将失败,编译器提示
error C1070: 文件中的 #if/#endif 对不匹配
error C2162: 应输入宏形参
3.宏的一个连接多个字符的用法
例如:
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define PRINTF(s) /
if (s) /
printf(s); /
#define _VAL(x) #x
#define PRINTF(s) /
if (s) /
printf(s); /
void _tmain(int argc, _TCHAR* argv[])
{
//_ASSERTE(0);
PRINTF(__FILE__ " - " _STR(__LINE__));
}
{
//_ASSERTE(0);
PRINTF(__FILE__ " - " _STR(__LINE__));
}
将 __FILE__ 和 __LINE__传递给一个str来输出
4. 编译时检查宏开关
#ifdef _X86
#ifdef _X86
#Pragma message(“_X86 macro activated!”)
#endif
5.当在宏里面使用临时变量定义,或者使用代码块的时候要注意使用区间包含
例如:
#define PRINTF(s) /
if (strchr(s,'F')) /
printf(s##"/n"); /
if (strchr(s,'F')) /
printf(s##"/n"); /
void _tmain(int argc, _TCHAR* argv[])
{
int i = 1;
if (i)
PRINTF("TRUE")
else
PRINTF("FALSE")
system("pause");
}
从上面这段代码的结果,可以看出,逻辑是完全错误的!
{
int i = 1;
if (i)
PRINTF("TRUE")
else
PRINTF("FALSE")
system("pause");
}
从上面这段代码的结果,可以看出,逻辑是完全错误的!
遇到这种情况,请使用{},或者do{}while(0);来定义局部区间
例如
#define PRINTF(s) /
{ /
if (strchr(s,'F')) /
printf(s##"/n"); /
} /
这样定义就没有问题了。
#define PRINTF(s) /
{ /
if (strchr(s,'F')) /
printf(s##"/n"); /
} /
这样定义就没有问题了。
6.调试复杂的宏块最好的办法,就是直接查看输出的预编译文件,在vc下就是 /P 编译开关,MSDN相关解释如下:
项预处理 C 和 C++ 源文件并将预处理输出写入文件。此文件具有与源文件相同的基名称和 .i 扩展名。在此过程中,执行所有的预处理器指令,执行宏展开,并移除注释。若要将注释保留在预处理输出中,请将 /C 选项与 /P 一起使用。
/P 将 #line 指令添加到输出中,添加的位置是每个包含文件的开头和结尾以及被条件编译预处理器指令移除的行的周围。这些指令将预处理文件中的行重新编号。因此,在处理后期生成的错误引用原始源文件的行号而不是预处理文件中的行的行号。若要取消生成 #line 指令,请使用 /EP 和 /P。
/P 选项取消编译。它不产生 .obj 文件,即使使用 /Fo 也是如此。必须重新提交预处理文件以进行编译。/P 还取消 /FA、/Fa 和 /Fm 选项的输出文件。
在 Visual Studio 开发环境中设置此编译器选项
- 打开此项目的“属性页”对话框。有关详细信息,请参见设置 Visual C++ 项目属性。
- 单击“C/C++”文件夹。
- 单击“预处理器”属性页。
- 修改“生成预处理文件”属性。
以编程方式设置此编译器选项
请参见 GeneratePreprocessedFile 属性。
示例
下列命令行预处理 ADD.C
,保留注释,添加 #line 指令,并将结果写入文件 ADD.I
:
CL /P /C ADD.C
请参见
编译器选项 | 设置编译器选项
- 有关宏的使用总结 - 1 (VS编译器)
- 在命令行下使用vs的编译器
- vs编译器cl使用
- 有关使用React的总结
- 有关shared_ptr的使用总结
- C#编译器VS的一些工具的使用
- 使用vs编译器编译一个简单的dll项目
- Opencv + Qt(VS编译器MSVC版本)的使用
- VS中使用nasm汇编编译器的方法
- vs编译器使用时的问题及解决方案
- C++有关编译器的笔记
- Linux下gcc编译器的使用总结
- 编译器中和64位编程有关的预定义宏
- 编译器中和64位编程有关的预定义宏
- IAR编译器使用问题总结-1
- VS编译器的记忆问题
- 有关TinyXML使用的简单总结
- 有关TinyXML使用的简单总结
- 信号驱动io
- IE7编码解析错误导致页面变成白板
- pthread 互斥实例
- Apche LoadModule报错
- mysql笔记4
- 有关宏的使用总结 - 1 (VS编译器)
- strlen与sizeof的区别
- 显著改善桌面性能的200+行Kernel补丁
- 一个完整的Installshield安装程序实例—---基本设置二
- 常用linux命令
- (一)PetShop的系统架构设计
- Oracle 中实现查找树形结构节点功能
- 一个完整的Installshield安装程序实例 --高级设置一
- effective C++ 条款18 to 条款24