命名空间包含是否会增加exe文件的大小?

6
我参加了一个会议,会议上讲解到我们不应该使用"using namespace std",而是用"std::cout"来调用std命名空间的某些函数,这将增加二进制文件的大小
我尝试通过以下实验验证了这一点。代码和输出如下:
    [Fooo@EXP]$ cat namespacestd.cpp
    #include<iostream>

    #ifdef STD
            using namespace std;
    #endif

    int main()
    {
    #ifndef STD
            std::cout<<"\n ==> Workign \n";
    #else
            cout<<"\n ==> Workign \n";
    #endif

    return 0;

    }


    [Fooo@EXP]$ time g++ -c namespacestd.cpp -DSTD

    real    0m0.246s
    user    0m0.215s
    sys     0m0.030s
    [Fooo@EXP]$ size namespacestd.o
       text    data     bss     dec     hex filename
        310       8       1     319     13f namespacestd.o  
    [Fooo@EXP]$ time g++ -c namespacestd.cpp

    real    0m0.258s
    user    0m0.224s
    sys     0m0.034s
    [Fooo@EXP]$ size namespacestd.o
       text    data     bss     dec     hex filename
        310       8       1     319     13f namespacestd.o

    [Fooo@EXP]$ time g++ -o namespacestd namespacestd.cpp -DSTD

    real    0m0.293s
    user    0m0.251s
    sys     0m0.042s
    [Fooo@EXP]$ size namespacestd
       text    data     bss     dec     hex filename
       1980     580     288    2848     b20 namespacestd
    [Fooo@EXP]$ time g++ -o namespacestd namespacestd.cpp

    real    0m0.274s
    user    0m0.239s
    sys     0m0.035s
    [Fooo@EXP]$ size namespacestd
       text    data     bss     dec     hex filename
       1980     580     288    2848     b20 namespacestd
    [Fooo@EXP]$

根据我的实验,我发现

二进制文件的大小没有影响

唯一的区别在于

编译时间有所不同.

如果我的结论有误,请指出

谢谢


编译时间可能会有所不同(例如,using 可能会导致更多的工作),但这只是理论上的问题。 - Matthieu M.
除非重复试验显示出一致的差异,否则我不会过多关注编译时间上的差异。g++将至少编译几十个文件来编译该程序,而时间可能会有所变化。 - Steve Jessop
我同意编译时间是无关紧要的。 - AnotherDeveloper
4个回答

3

在大多数编译器中,使用using namespace std不应该影响二进制大小。但是,还是应该避免使用它的另一个原因:

命名空间std非常大。里面有数千个标识符,它们都在程序的作用域内。这增加了与您自己的标识符或其他库的标识符发生冲突的可能性,可能会引起一些不愉快的意外。

请参见相关问题:为什么在C++中使用using namespace std被认为是一种不好的做法?


2

二进制文件的大小不会受到影响

对于可执行代码和数据来说,应该没有任何区别,因为在两种情况下,您都是对同一对象进行相同的操作,并且从名称查找该对象的过程发生在编译期间。但是,在某些情况下,它们可能会生成不同数量的元数据,例如调试信息。

编译时间会有所差异

对源代码进行任何更改都可能改变编译时间,但是您没有提供足够的数据来确定差异是否具有统计学意义。您需要针对每个配置重复多次实验,计算两个样本的均值和方差,并对平均值的差异应用显着性测试。

无论如何,即使您确定污染全局命名空间可以使编译速度略微加快,任何节省的时间都将与跟踪名称冲突可能浪费的时间相比微不足道。在std命名空间中有很多名称,其中许多名称可能会在您自己的代码中使用。这就是避免命名空间污染的原因;任何声称它会影响二进制文件大小的人都没有完全理解他们所说的内容。


2
我参加了一场培训,学到我们不应该使用"using namespace std",而是用"std::cout"来使用std命名空间的某些调用,因为这样可以增加二进制文件的大小。这是非常好的建议,但这个理由是毫无意义的优化,而且还是错误的。在头文件中永远不要使用"using namespace std;"。在头文件中使用该指令会在每个包含您的头文件的文件中污染全局命名空间,导入std命名空间的项目。即使在源文件中,许多人也更喜欢使用"std::whatever",因为它使代码更易读、更易懂,也更不容易出错。以几个字符的输入成本为代价,那个"std::"前缀将永远向编译器传达意图,更重要的是,向代码的人类读者/维护者传达意图。毫无疑问,代码正在调用标准库中的某些内容。唯一使用"using namespace ;"指令的理由是程序员的懒惰,为了节省几个字符的输入而已。这几个节省下来的字符的输入成本是巨大的。

2

这两个二进制文件不同,因为其中一个定义了STD,而另一个没有。我还得到了不同的大小。

然而,如果你剥离符号,你将会得到几乎相同的二进制文件(不同的是一些ELF头参数,例如编译时间)。

如果你将示例更改为:

#include<iostream>

    using namespace std;


    int main()
    {
    #if 0
            std::cout<<"\n ==> Workign \n";
    #else
            cout<<"\n ==> Workign \n";
    #endif

    return 0;

    }

使用#if 1#if 0编译后,即使不去除符号,你也会得到相同大小的二进制文件。

编译时间的差异是正常的。定义了宏后,文件变得更大,预处理器需要执行更多操作。然而,新的个人电脑如此强大,以至于我建议忽略这种时间增加。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接