为什么我的代码在共享对象中重复?

huangapple go评论58阅读模式
英文:

Why is my code duplicating with shared objects?

问题

我有一个公共头文件,被包含在多个cpp文件中,然后我编译每个cpp文件以生成.so文件。但当我使用最终的可执行文件执行时,我发现公共头文件被重复包含,也就是说,在cpp文件中包含的次数多少,头文件中的所有语句都会被执行多少次。

如何避免这种情况?

公共头文件是:

// common.h
#ifndef _COMMON_H
#define _COMMON_H

#include <iostream>

int funcC();
const int x = funcC();

#endif // COMMON_H

其他文件如下:

// common.c
#include "common.h"
#include <iostream>
int funcC() {
    std::cout << "HI HI HI" << std::endl;
    return 2;
}
// main1.c
#include "common.h"

int main() {
    return 0;
}

我原本期望它只打印一次“HI HI HI”,但它打印了两次。

英文:

I have a common header file being included in multiple cpp files I then compile to make the .so files of each cpp . But when I execute with the final executable, I am seeing that the common header file is being duplicated in the sense that all statements in that header file are being hit as many times as it has been included in the cpp.

How to avert it?

The common header file is:

    // common.h 
    #ifndef _COMMON_H 
    #define _COMMON_H 

    #include&lt;iostream&gt; 

    int funcC(); 
    const int x = funcC(); 

    #endif // COMMON_H 

The other files are:

    // common.c 
    #include &quot;common.h&quot; 
    #include &lt;iostream&gt; 
    int funcC() { 
        std::cout&lt;&lt;&quot;HI HI HI&quot;&lt;&lt;std::endl; 
        return 2; 
    } 

and

    // main1.c 
    #include &quot;common.h&quot; 

    int main() { 
        return 0; 
    } 

I was expecting it you print "HI Hi Hi" only once, but it's printing twice

答案1

得分: 4

这是一个定义:

int x;

这是相应的声明:

extern int x;

如果你将一个定义放在头文件中并多次包含该头文件,那么你将得到多个定义。一般来说,这是一个错误,尽管有例外情况。然而,拥有多个声明是可以的(只要它们都相同),所以一般来说你只在头文件中放置声明。

在C++中还有一个额外的规则(但不适用于C),即const变量自动具有局部作用域(类似于将它们声明为static)。这就是为什么你上面的代码不会导致多重定义错误的原因,尽管你对x进行了多次定义,但每次都是在它所出现的翻译单元中局部的。如果你去掉const,就会得到一个多重定义错误。

下面是你问题的一个可能解决方案:

// common.h
extern const int x; // 这是一个声明

// common.cpp
extern const int x = funcC(); // 这是一个定义

在common.cpp中的奇怪结构是你必须在C++中定义一个非局部作用域的常量的方式。const默认是局部作用域,extern覆盖了这一点,然后初始化器= funcC()将本来可能是一个声明的东西变成了一个定义。

英文:

This is a definition

int x;

This is the corresponding declaration

extern int x;

If you put a definition is a header file and include the header file multiple times, then you will get multiple definitions. Generally speaking that is an error, although there are exceptions. However it's fine to have multiple declarations (as long as they are all the same) so that is why generally speaking you only put declarations in header files.

There is an additional rule in C++ (but not C) that const variables automatically have local scope, (similar to declaring them static). That is why your code above does not result in a multiple definition error, although you do have multiple definitions of x each is local to the translation unit in which it appears. If you removed the const you would get a multiple definition error.

Here then is a possible solution to your problem

// common.h
extern const int x; // this is a declaration

// common.cpp
extern const int x = funcC(); // this is a definition

The strange construct in common.cpp is the way you must define a non-locally scoped constant in C++. const is by default local scope, extern overrides that, and then the initializer = funcC() turns what would otherwise be a declaration into a definition.

huangapple
  • 本文由 发表于 2023年7月20日 13:08:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76726825.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定