加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

为什么c将在单独模块中定义的同名变量放入内存中的相同地址?

发布时间:2020-12-16 10:20:58 所属栏目:百科 来源:网络整理
导读:我们来看头文件var.h #include iostreamclass var {public: var () {std::cout "Creating var at " this std::endl; } ~var () {std::cout "Deleting var at " this std::endl; } }; 和两个源文件,首先是lib.cpp #include "var.h"var A; 和第二个app.cpp #in
我们来看头文件var.h

#include <iostream>

class var
  {public:
      var () {std::cout << "Creating var at " << this << std::endl; }
      ~var () {std::cout << "Deleting var at " << this << std::endl; }
  };

和两个源文件,首先是lib.cpp

#include "var.h"
var A;

和第二个app.cpp

#include "var.h"

var A;

int main ()
  {return 0;
  }

那么,如果我试图编译它们

g++ -c app.cpp
g++ -c lib.cpp
g++ -o app app.o lib.o

链接器返回多个定义的变量错误.但是,如果我将它编译到共享库主应用程序

g++ -fPIC -c lib.cpp
g++ --shared -o liblib.so lib.o
g++ -fPIC -c app.cpp
g++ -o app -llib -L . app.o

它没有错误地链接.但是程序无法正常工作:

./app
Creating var at 0x6013c0
Creating var at 0x6013c0
Deleting var at 0x6013c0
Deleting var at 0x6013c0

所以在同一个内存地址创建了不同的变量!例如,在库和应用程序期望它们具有不同的值(在这种情况下为对象字段的值)的情况下,它可能会遇到严重的麻烦.

如果类var做内存分配/删除valgrind警告有关访问最近删除的块中的内存.

是的,我知道我可以放静态变量A;而不是var A;并且两种编译方式都能正常工作.我的问题是:为什么不能在不同的库中使用同名变量(甚至函数?)?图书馆创建者可能对彼此使用的名称一无所知,也不会被警告使用静态.为什么GNU链接不会警告这种冲突?

并且,顺便说一下,可能会遇到同样的麻烦吗?

UPD.谢谢大家解释有关命名空间和extern的问题,我看到为什么相同的符号被放入相同的内存地址,但我仍然无法理解为什么没有显示链接错误甚至是关于双重定义变量的警告,而是在第二种情况下产生了错误的代码.

解决方法

My question is: why one can’t use same-named variables (or even functions?)
in different libraries?

您可以.你遗漏的是声明

var A;

没有定义在库中使用的符号A.他们定义了要导出的符号,以便任何其他编译单元可以引用它!

例如如果,在app.cpp中,你声明了

extern var A;

这意味着声明“A是一个var类型的变量,其他一些编译单元将定义和导出” – 通过对您的设置进行此修改,这将使app.cpp显式请求使用名为A的对象lib. cpp导出.

您的设置问题是您有两个不同的编译单元都试图导出相同的符号A,这会导致冲突.

Why GNU linked doesn't warn about this conflict?

因为GNU无法知道您希望A成为编译单元的私有变量,除非您告诉GNU它应该是您的编译单元的私有.这就是静态在这种情况下的含义.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读