编译依存关系高手请进linux环境

toadzw 2011-04-18 08:34:05
//car.h

#include <stdio.h>
#include <stdlib.h>


class CAR{
private:
int carnum;
public:
void getCarName();


};
//car.cpp
#include "car.h"
void CAR::getCarName(){
printf("toad\n");
printf("toad\n");
carnum=0;
printf(" %d \n",carnum);
}

//main.cpp
#include <stdio.h>
#include <stdlib.h>
#include "car.h"
using namespace std;
int main(){
CAR car1;
car1.getCarName();

return 0;
}

我把car类编译成了一个.so库,按照编译依存关系来说,我改变了car.h中的内容,原先把有int carnum这个值,我重新编译了.so,但是main.cpp没有重新编译啊,按照道理说在main.cpp中我引用的是car对象啊,应该main.cpp也要重要编译才可能正确运行啊,可没有便宜main也能通过,我就奇怪了,那么编译依存说法应该说不通啊,如果是使用动态分配的car我还是可以理解的,使用对象实在理解不了main为什么不用重新编译;



...全文
256 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
jackzhhuang 2011-04-20
  • 打赏
  • 举报
回复
理论上讲必须重新编译main

因为你直接使用了Car这个类,他的存储结构发生了变化,如不重编,是有可能出问题的。
tangquan261 2011-04-19
  • 打赏
  • 举报
回复
由于函数借口没有变化,同时由于是动态库,在运行时才参与连接。所以,动态库函数变化,不会影响函数调用,对于main来说。他看到的是什么都没变。
  • 打赏
  • 举报
回复
.h是链接的时候才用得到的。

我想应该是这样的吧。
昵称很不好取 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 toadzw 的回复:]
-fPIC 搞什么飞机的,哈哈,你们这样关注,我都不好意思走了
[/Quote]
自己搜,呵
toadzw 2011-04-18
  • 打赏
  • 举报
回复
-fPIC 搞什么飞机的,哈哈,你们这样关注,我都不好意思走了
昵称很不好取 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 toadzw 的回复:]
算了,准备回去睡觉了,还没有吃晚饭
[/Quote]
这么勤奋啊,赞一个
huofen2005 2011-04-18
  • 打赏
  • 举报
回复
差不多吧,主要是对象在内存里面的布局不能变;
成员顺序,虚函数顺序一般是声明里面决定了的;不知道有没有可能不改声明的前提下变换其布局!
函数地址无所谓,链接时候会自动重定位的;
昵称很不好取 2011-04-18
  • 打赏
  • 举报
回复
编译.so文件时候是否用-fPIC选项?
qq120848369 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 toadzw 的回复:]
那是不是.h如果内容不变,只改变了.cpp的实现,是不是就永远不用重编译main了啊
[/Quote]

没错!

只要接口不变,说白了就是main.cpp里边的东西都没变,包括#include进来的.h,你就不需要重新编译。
toadzw 2011-04-18
  • 打赏
  • 举报
回复
算了,准备回去睡觉了,还没有吃晚饭
toadzw 2011-04-18
  • 打赏
  • 举报
回复
那是不是.h如果内容不变,只改变了.cpp的实现,是不是就永远不用重编译main了啊
huofen2005 2011-04-18
  • 打赏
  • 举报
回复
越界操作,特别是访问操作,往往是不出错的;
要项目里面出现这种情况,往往是隐藏很深的错误了~
qq120848369 2011-04-18
  • 打赏
  • 举报
回复
的确,不出错只能是运气,因为main引入.h,内容已经改变了,不重新编译本身就是不合理的。
huofen2005 2011-04-18
  • 打赏
  • 举报
回复
DLL升级的时候,接口是允许不改变;
如果是C++的DLL,你要升级的话,接口类也是不允许动的,动了的话,客户端就要重新编译;
==> 把接口类往大里整,用原来的方式访问往往是不会出错的,有点像用基类接口访问子类对象一样的效果!
==> 不出错是运气;
toadzw 2011-04-18
  • 打赏
  • 举报
回复
我试了一下,减小也是可以不用重新编译,不信你自己试一下
huofen2005 2011-04-18
  • 打赏
  • 举报
回复
class CAR{
private:
int carnum;
char thefuckcarname[100];
public:
void getCarName();
};

把名字缓存起来打印看看,该挂了吧?
你的修改是把对象扩大了,按原来的接口是访问是ok的,把对象缩小,再按原来的布局访问,应该会越界拉~
toadzw 2011-04-18
  • 打赏
  • 举报
回复
哈哈,这样改了肯定是挂了但为什么不改函数名就不挂呢
huofen2005 2011-04-18
  • 打赏
  • 举报
回复
把 void getCarName(); 改成 void getTheFuckCarName(); 看看,应该挂了吧!
qq120848369 2011-04-18
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 toadzw 的回复:]
我也是这样想的,所以加了这句printf(" %d \n",carnum);也还不用,真是疯了都
[/Quote]

应该可以打印出正确的结果吧.

毕竟main里调用方式没改变,调用后就交给.so去做了,.so是重新编译过的,它完全能够找到那个变量做操作.

toadzw 2011-04-18
  • 打赏
  • 举报
回复
又试了一次,还是一样,可以通过
加载更多回复(8)

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧