搜索文档搜索当前语言
语言参考
候选版本v0.20260809.0-rc.5

本文档对应当前协同发布候选版本。

语言参考

C2Go 扩展速查

检索 C2Go 提供的 attribute、宏、builtin、pragma、selector 与 ABI 类型。

这些名称并不是同一种“新关键字”。<c2go.h> 提供宏和声明,Clang 则提供 attribute、builtin、pragma 与预定义宏。阅读诊断或编写可复用 header 时,必须先分清它们的类别。

最小使用模式

没有 active pragma region 时,默认 world 是 unmanaged。有定义的函数属于内部 C2Go 代码;只有声明、没有定义的函数默认是 native import,除非显式扩展另有指定。

#include <c2go.h>

#pragma c2go managed push
struct Node {
    struct Node *next;
    long value;
};
#pragma c2go pop

c2go_extern long node_value(const struct Node *node) {
    return node->value;
}

无参数 managed 会启用 function、pointer 与 record 三个 managed 默认项,适合大多数 managed region。函数带有 c2go_extern,因此会导出给 Go。

World、导出与链接 attribute

公开拼写 类别 作用对象 用途 主要限制
managed <c2go.h> 宏 → c2go_managed attribute Record、field、pointer、parameter、variable、function 显式进入 Go managed world。 Pointer layout 必须始终对 GC 可见。
unmanaged <c2go.h> 宏 → c2go_unmanaged attribute 同一组声明类别 保持 native C 表示或 ABI 边界。 Pointer 跨调用不代表 Go GC 自动取得所有权。
c2go_extern 宏 → c2go_extern attribute C definition 及其先前 declaration 通过生成的 Go package 导出 C symbol。 所有 redeclaration 必须一致;默认 Go 名称按下划线分段转 CamelCase。
c2go_extern_as(selector) Attribute 宏 导出的 definition 选择 Go identifier 的大小写规则。 必须使用已记录的 selector 常量。
c2go_linkname("pkg.Symbol") 变参 attribute 宏 函数 declaration 将 C declaration 绑定到具名 Go symbol。 Declaration 必须与 Go ABI shape 匹配。
c2go_linkname("pkg.Symbol", C2GO_GOABI0) 带 ABI selector 的 attribute 宏 函数 declaration 直接绑定到已经暴露 ABI0 的 symbol。 ABIInternal-only Go 函数不能选择 ABI0。
c2go_returntype(struct T) Attribute 宏 已 link/export 的函数 把完整 C struct 的字段解释成独立 Go result slot。 每个字段都必须是受支持的单 slot result,声明返回类型必须正好是 struct T。
__attribute__((c2go_variant)) Clang attribute Union declaration 请求 GC 可表示的 union layout。 无法消歧的重叠 pointer layout 会被拒绝。

按任务学习的示例见将 C 导出给 Go和从 C 调用 Go。

只有声明、没有定义的函数默认就是 native import;导入普通原生函数不要求写 unmanaged extern。只有当声明必须永久保持 import-only,或函数指针参数/返回值需要 host-callback 类型规则时,才显式使用 unmanaged。

Managed 分配与类型信息

公开拼写 类别 结果
gc_malloc(type_info, size) 声明的 runtime 函数 使用给定 runtime type descriptor 分配清零的 Go heap storage。
c2go_typeinfo(T) 宏 → __c2go_typeinfo compiler builtin 取得 managed record type 对应的 runtime._type descriptor。
gc_malloc_array(type_info, elem_size, count) Static inline helper 使用 element descriptor 分配连续 managed array。

应使用 c2go_typeinfo(struct Node),不要手工构造 descriptor:

struct Node *node = gc_malloc(
    c2go_typeinfo(struct Node),
    sizeof(struct Node)
);

普通 malloc、calloc、realloc、free 仍是 unmanaged C allocator API。所有权规则见 GC 感知分配。

函数指针跨界

公开拼写 类别 方向 用途
c2go_callback(fn) 宏 → compiler builtin C2Go function → native callable pointer 把 C2Go 函数交给 comparator 等 native callback API。
c2go_callout(fn) 宏 → compiler builtin Native import → internal callable pointer 存储或传递某个 native import 的可调用指针;直接调用不需要它。
C2GO_DYN(name) Token-pasting 宏 Native import 命名 导入 host symbol,同时允许 package 自己定义/导出相同裸 C 名称。

这些形式不能与 &fn 互换。Raw native address 与 C2Go callable wrapper 使用不同调用契约,详见回调。

Pragma region

支持的形式是:

#pragma c2go managed push  /* 推荐:启用全部 managed 默认项 */
/* declarations */
#pragma c2go pop

#pragma c2go managed(C2GO_PTR | C2GO_RECORD) push  /* 仅在需要精细控制时使用 */
/* declarations */
#pragma c2go pop

#pragma c2go unmanaged push
/* declarations */
#pragma c2go pop

无参数 managed 等价于启用 C2GO_FUNC | C2GO_PTR | C2GO_RECORD,是一般场景的默认选择。只有需要关闭其中某项行为时才使用 managed(N);它接受整数或宏,并允许使用括号和按位 OR(|)组合。宏会先展开,再计算掩码;最终值必须在 0..7 范围内。这里有意不接受 +、- 等其他表达式运算符。

Bit Header 名称 Region 内效果
1 C2GO_FUNC 只有声明的函数默认成为内部 C2Go reference,而不是 native import。
2 C2GO_PTR 未注解的 pointer-shaped declaration 默认变为 managed。
4 C2GO_RECORD 完成定义的 record 参与 managed-record inference。

例如,managed(C2GO_PTR | C2GO_RECORD) 不启用 function bit,因此区域内只有声明的函数仍按 native import 处理。unmanaged push 等价于零 mask。Region 可以嵌套,每个 pop 只退出一层。

Selector 常量

常量 值 用于 含义
C2GO_EXPORTED 1 c2go_extern_as 生成常规 exported CamelCase Go identifier。
C2GO_KEEPCASE 0 c2go_extern_as Go 源码 identifier 保留 C 拼写。
C2GO_GOABI0 1 c2go_linkname 目标 symbol 已经提供 ABI0 entry。

Go 边界类型

C 类型 Go shape 已发布 64 位 target 上的布局
c2go_slice []T data pointer、length、capacity
c2go_string string data pointer、length
c2go_iface interface value table pointer、data pointer
c2go_error error 同样的双字 non-empty-interface shape

它们只是 ABI 表示,不是在 C 中实现 Go 语言操作。当前不能动态 dispatch interface method;应绑定具名 Go wrapper。详见边界数据类型。

预定义模式宏

C2Go 模式下会定义 __C2GO__ 与 __clang_c2go__。它们适合小范围兼容分支:

#if defined(__C2GO__)
#  include <c2go.h>
#endif

不能通过 mode macro 推断 target 支持范围。发布矩阵和硬边界以平台与当前限制为准。