delphij's Chaos

选择chaos这个词是因为~~实在很难找到一个更合适的词来形容这儿了……

12 Feb 2025

C++ 中的 main 定义

新的 C++ 标准中 不允许给 main 指定 linkage-specification 了。

当然,考虑到原本 main() 也是 C 运行环境在开始运行程序的时候调用的, 而 C 运行环境自然也预期 C linkage,即不按照 C++ 的习惯对符号根据参数增加名字前缀, 因此大部分编译器在遇到 C++ 程序定义全局 main() 的时候也会按照习惯采取 C linkage 方式去翻译。这一规则首先被 GCC 采纳,随后 LLVM 也跟进了。

然而我今天遇到一个奇葩彻底把我雷到了。此君是在一个 C++ namespace 中定义的 main, 故而此君用到了:

namespace foo::bar::baz {
    // ...
    extern "C" int main() {
        // ...
    }
}

「这题我会」,我想,不就是把 int main() 前面的 extern "C" 去掉吗?完全没注意到前面说的 namespace。 更为精妙的是,此君在 main 中调用了该名字空间的方法。

写得挺好的,下回别再这么写了。

入侵性最小的解法,便是在名字空间外定义一个新的 main 函数去调用名字空间里面那个。换言之,还是去掉 extern "C", 但是在名字空间外再定一个 main() 去调用它:

int main() {
    return foo::bar::baz::main();
}

实在是有些 dirty。