有关宏的使用总结 - 1 (VS编译器)
2010-11-19 13:08
330 查看
11月9日
1.宏的分段式定义一定要注意,不能在 / 后面有任何的字符,包括空格
例如:
#define PRINTF(s) /
printf(s##"/n");
如果 #define PRINTF(s) / 这句的后面还有多余的空格,那么vc编译器将提示
error C2017: 非法的转义序列
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
如果此两处中任意一处加上了"/",编译将失败,编译器提示
error C1070: 文件中的 #if/#endif 对不匹配
error C2162: 应输入宏形参
3.宏的一个连接多个字符的用法
例如:
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define PRINTF(s) /
if (s) /
printf(s); /
void _tmain(int argc, _TCHAR* argv[])
{
//_ASSERTE(0);
PRINTF(__FILE__ " - " _STR(__LINE__));
}
将 __FILE__ 和 __LINE__传递给一个str来输出
4. 编译时检查宏开关
#ifdef _X86
#Pragma message(“_X86 macro activated!”)
#endif
5.当在宏里面使用临时变量定义,或者使用代码块的时候要注意使用区间包含
例如:
#define PRINTF(s) /
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");
}
从上面这段代码的结果,可以看出,逻辑是完全错误的!
遇到这种情况,请使用{},或者do{}while(0);来定义局部区间
例如
#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 属性。
请参见
有关宏的使用总结 - 1 (VS编译器)
今天下午被宏折腾了好久,是时候,该好好总结一下有关于宏的使用了。1.宏的分段式定义一定要注意,不能在 / 后面有任何的字符,包括空格
例如:
#define PRINTF(s) /
printf(s##"/n");
如果 #define PRINTF(s) / 这句的后面还有多余的空格,那么vc编译器将提示
error C2017: 非法的转义序列
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
如果此两处中任意一处加上了"/",编译将失败,编译器提示
error C1070: 文件中的 #if/#endif 对不匹配
error C2162: 应输入宏形参
3.宏的一个连接多个字符的用法
例如:
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define PRINTF(s) /
if (s) /
printf(s); /
void _tmain(int argc, _TCHAR* argv[])
{
//_ASSERTE(0);
PRINTF(__FILE__ " - " _STR(__LINE__));
}
将 __FILE__ 和 __LINE__传递给一个str来输出
4. 编译时检查宏开关
#ifdef _X86
#Pragma message(“_X86 macro activated!”)
#endif
5.当在宏里面使用临时变量定义,或者使用代码块的时候要注意使用区间包含
例如:
#define PRINTF(s) /
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");
}
从上面这段代码的结果,可以看出,逻辑是完全错误的!
遇到这种情况,请使用{},或者do{}while(0);来定义局部区间
例如
#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
请参见
编译器选项 | 设置编译器选项
相关文章推荐
- vs使用时报错解决办法总结
- 根据错误代码使用VS自带的errlook.exe查看错误信息及常见错误信息代码含义总结
- VS2015快捷键使用总结
- VS经常使用的快捷键总结
- VS使用总结
- CMake入门1——CMake与VS编译器和nmake的结合使用
- VS中c++文件调用c 函数 ,fatal error C1853 预编译头文件来自编译器的早期版本号,或者预编译头为 C++ 而在 C 中使用它(或相反)
- VS2013使用教程总结(2)---显示行号
- vs2013 git 使用总结
- 关于使用VS生成Lua 5.2.3编译器与解释器 动态库 静态库
- 使用Intel编译器(1)并行化(3)自动并行化相关的选项和总结
- 使用vs编译器编译一个简单的dll项目
- VS2015使用经验总结
- vs使用总结
- VS2013 MFC中TeeChart控件画波形使用总结
- vs工具使用和问题总结
- 在Windows下使用命令提示符以及VS提供的CL编译器编译运行C/C++
- VS6.0单文档工程中,View界面想使用CListCtrl & list = GetListCtrl(); 问题总结
- IAR编译器使用问题总结-1
- VS快捷键使用总结