g++ –E hello.cpp -o hello.i //将hello.c预处理输出hello.i
g++ -S hello.i -o hello.s //将预处理输出文件hello.i汇编成hello.s文件
g++ -c hello.i -o hello.o //将预处理输出文件hello.i汇编成hello.s文件
g++ hello.o -o hello //将预处理输出文件hello.i汇编成hello.s文件
#define macro-name replacement-text
#include <iostream>
using namespace std;
#define PI 3.14159
int main ()
{
cout << "Value of PI :" << PI << endl;
return 0;
}
现在,让我们测试这段代码,看看预处理的结果。假设源代码文件已经存在,接下来使用 -E 选项进行编译,并把结果重定向到 test.p
$ gcc -E test.cpp > test.p
...
int main ()
{
cout << "Value of PI :" << 3.14159 << endl;
return 0;
}
#include <iostream>
using namespace std;
#define MIN(a,b) (a<b ? a : b)
int main ()
{
int i, j;
i = 100;
j = 30;
cout <<"较小的值为:" << MIN(i, j) << endl;
return 0;
}
#include <iostream>
using namespace std;
#define DEBUG
#define MIN(a,b) (((a)<(b)) ? a : b)
int main ()
{
int i, j;
i = 100;
j = 30;
#ifdef DEBUG
cerr <<"Trace: Inside main function" << endl;
#endif
#if 0
/* 这是注释部分 */
cout << MKSTR(HELLO C++) << endl;
#endif
cout <<"The minimum is " << MIN(i, j) << endl;
#ifdef DEBUG
cerr <<"Trace: Coming out of main function" << endl;
#endif
return 0;
}
#ifdef NULL
#define NULL 0
#endif
#include <iostream>
using namespace std;
#define MKSTR( x ) "first"#x
#define CLASS_NAME(name) aaa##name
#define MERGE(x,y) x##y##x
char aaaTimer[] = "this is aaaTimer";
int meTome = 10;
int main ()
{
cout << MKSTR(HELLO C++) << endl;
cout << CLASS_NAME(Timer) << endl;
cout << MERGE(me,To) << endl;
return 0;
}
-> % ./a.out
firstHELLO C++
this is aaaTimer
10
它是编译阶段里检测各种条件的“断言”,编译器看到 static_assert 也会计算表达式的值,如果值是 false,就会报错,导致编译失败。 static_assert 是“静态断言”,在编译阶段计算常数和类型,如果断言失败就会导致编译错误。它也是迈向模板元编程的第一步。
比如说,这节课刚开始时的斐波拉契数列计算函数,可以用静态断言来保证模板参数必须大于等于零:
char* p = nullptr;
static_assert(p == nullptr, "some error."); // 错误用法
它用来断言一个表达式必定为真。比如说,数字必须是正数,指针必须非空、函数必须返回 true
assert(i > 0 && "i must be greater than zero");
assert(p != nullptr);
assert(!str.empty());
assert 的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向 stderr 打印一条出错信息,然后通过调用 abort 来终止程序运行。
使用 assert 的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。
在调试结束后,可以通过在包含 #include 的语句之前插入 #define NDEBUG 来禁用 assert 调用,示例代码如下