new 所得block in VC

动态分配所得内存块 in VC

分别debug mod 和 release

debug

两个cookie + 32 + 4,如果数组 +4,VC下内存块16字节对齐 + 本身内存对齐大小

使用#define和#undef限制宏作用域,不要加;,否则会被当作程序体;宏展开只是在预处理阶段单纯的文本替换,例如类型别名时并不具有类型定义说明的功能,一些常见宏使用如__LINE__ __FUNCTION__ __FILE__

#if #ifdef条件判断,例如#ifdef __cplusplus extern "c"{ #endif

宏定义执行体通过 do{}while(0)保证执行体里一定都被执行一次,比如在if后使用宏等,当参数为表达式时给每个参数加上(),例如#define mul(a, b) a*b add(1+2,3+4)即出现歧义

使用#将参数转换为字符 #define str(x) #x

使用##表示连接两个参数#define cont(a,b) a##b

相当于ab拼接起来,在sylar的源码中就有大量宏用法

#define XX(name) name##_fun name##_f = nullptr;

以上两种宏参数不会展开,通过延长#和##可以实现参数转换,这样str(INT_MAX)的到的就是“0xffffffff”

1
2
#define _str(x) #x
#define str(x) _str(x)

#@ 表示将单字符转换为字符 参数不能超过四个字符 转换最后一个

宏可变参...和__VA_ARGS__如sylar的日志库的应用,用va_list变量存储参数列表,va_start提供最后一个固定参数,初始化va_list变量,va_end释放资源;通过va_args获取下一个参数类型,比如va_arg(al, int)

1
2
3
4
5
6
7
8
9
10
11
#define SYLAR_LOG_FMT_LEVEL(logger, level, fmt, ...) \
if(logger->getLevel() <= level) \
sylar::LogEventWrap(sylar::LogEvent::ptr(new sylar::LogEvent(logger, level, \
__FILE__, __LINE__, 0, sylar::GetThreadId(),\
sylar::GetFiberId(), time(0), sylar::Thread::GetName()))).getEvent()->format(fmt, __VA_ARGS__)
void LogEvent::format(const char* fmt, ...) {
va_list al;
va_start(al, fmt);
format(fmt, al);
va_end(al);
}