正在从未命名的命名空间中执行代码

Executing code from within unnamed namespace

本文关键字:执行 代码 命名空间 未命名      更新时间:2023-10-16

我自己有一个工具包,其中包含一堆函数。我还有一个主程序,它链接到这个工具包,所以它可以使用它的功能。

工具包来源:

#include <iostream>
using namespace std;
namespace {
    int foo() {
       cout << "doing foo" << endl;
       return 0;
    }
    int tmp = foo(); // can't just call foo() without an assignment, compiler complains
}
// bunch of useful functions

MainProg来源:

#include <iostream>
#include "toolkit_header.h"
using namespace std;
int main() {
       // fiddle about for a while
       cout << "using toolkit functions..." << endl;
       // start using toolkit functions
       return 0;
}

这将输出:

doing foo
using toolkit functions...

让工具箱中的一个函数在每个main()开始时自动执行,并与之链接,这对我来说非常有用(有很多这样的功能,要求所有mainprog在开始时显式调用该函数不是一个可接受的解决方案),但这感觉像是一件坏事。这样做有什么严重的错误吗?

我在谷歌上搜索过,但这似乎是一个很难找到的问题,因为有很多关于调用未命名名称空间中的函数的热门话题。

您是否意识到您的工具箱代码在执行main之前就已经执行了?发布的代码实际上是100%可以的,在任何方面都不是坏事。

当您尝试使用工具化静态初始化程序中其他文件中的其他静态对象时,可能会出现问题,因为它们的初始化顺序没有定义。事实上,您已经在使用一个静态对象std::cout,除非您使用C++11或更高版本,否则cout此时不能保证初始化。启动C++11时,您有这个保证,所以这应该没问题。

从未命名的命名空间中执行代码

未命名命名空间中的代码的执行方式与命名命名空间或全局命名空间中的程序完全相同。

使工具箱中的函数在每个main()开始时自动执行的能力。。。但这感觉像是一件坏事。这样做有什么严重的错误吗?

实际上,函数是在main之前执行的。

可能存在问题。如果某个程序依赖于在初始化静态项目之前调用的函数,则无法保证会发生这种情况,除非依赖该函数的代码显式调用该函数。

如果可以接受的是,在静态初始化期间没有代码可能取决于正在执行的函数,那么应该没有问题。也就是说,如果你打算让工具包可供他人重复使用,那么你可能无法做出这种假设。如果工具箱的用户能够通过显式调用函数来决定什么时候执行某个东西,他们会很感激。

通过使用静态对象的构造函数,可以避免繁琐的int赋值

struct static_init {
    static_init() {
        cout << "doing foo" << endl;
    }
} static_init;

另外请注意,如果在代码中的其他地方(即.cpp文件中,因为它是未命名的命名空间)没有使用foo()或tmp,则链接器可能会对其进行优化,因此根本不会调用它。