函数调用规范
Naming | 调用规范 | 特点 | 好处 |
---|---|---|---|
__cdecl ( C declaration) | c/c++ 函数的默认调用规范。 | *参数由右向左 压入堆栈,由调用函数 (caller) 负责堆栈的清退。 * 手动清栈 |
好处, 可变参数。如printf. |
__stdcall( standard call) | *winapi | * 参数由左往右, 由被调用函数(CALLEE)负责堆栈的清退。 * 可变参数的时候转为 __cdecl |
|
__thiscall | c++ object , this call | * c++ object call 默认调用规范 * this pointer 直接保存在某寄存器 ecx |
|
__fastcall | c++ static function fast call | * 实参被保存在CPU 寄存器而不是函数堆栈。 | * 不能用于成员函数。 |
Note:
- 凡是接口函数都必须制定其调用规范。除非接口是非static 成员函数。
不同变成语言的软件进行联合开发
- 需要统一 函数,变量,数据类型,常量 等的连接规范 ( linkage specification)
- 通用的连接规范 extern "c"
如果仅对一个类型,函数
extern "C" void win_start(void)
如果是对一段代码
#ifdef __cplusplus
extern "C" {
#endif
const int MAX_AGE = 200
#pragma pack(push 4)
typedef struct Person
{
char * name;
int age
} Person_t;
#pragma pack(pop)
int __cdecl memcpy(const void *, const void *, size_t);
#ifdef __cplusplus
} // extern "C"
#endif
参数传递规则
- 输出参数在前
- 指针,输入,类型前加 CONST
- 值传递,输入 CONST &
返回值规则
- 不要把返回指针的函数作为左值, *func(&d) =200 不好
- 如果函数的返回值是一个对象,需要考虑return 语句的效率。返回的是 “对象的值”, “对象的指针” 还是“对象的引用“ , 部分场合可以使用返回引用来提高效率。看临时对象的内存分配方式,在栈上还是堆上
存储类型
存储类型 | 生存期限 | |
---|---|---|
extern | 永久 | 全局变量,全局函数 |
auto | 临时 | 局部变量,即进入函数的时候创建 |
static | 永久 | 显式地声明为static的全局变量或全局函数,一个编译单元 |
register | 临时 | 直接加载到cpu 寄存器 |
需要注意的是,
常量 = 局部静态变量
常量
void OutputString(const char *const str). 按顺时针螺旋法则, str -> const -> * > (char 类型)> const ; 理解, 常量指针;内容也是常量