股票学习网

股票学习网_股票入门基础知识_炒股入门知识 - - 股票学习网!

炒股为生1314新浪博客或tyj新浪博客

2024-03-17 23:33分类:MACD 阅读:

 

概述

为什么需要解读gcc/g++编译器对c/c++文件的影响呢?由于系统内核一般是使用C语言来编写的,系统内核中用C语言实现了很多库。而上层应用程序有可能是用C++来开发,如果在内核库函数头文件中不用extern“C”来声明库函数的话,在编写C++应用程序时,包含库头文件,在C++文件链接时就会以C++标准来链接库的函数名,而在库文件实现时是用C来实现的,二者函数名不同,在链接时就会出现找不到函数的现象。

实验环境

本次实验平台:Debian 9.4 gcc/g++版本:6.3.0 IDE环境:Qt Creator 4.2.0 qmake版本:3.0。这里可以看到最新的Debian系统对软件版本更新也是很及时的,对于电脑不能上外网情况,debian与centos都推出了离线包,两个系统都使用了很长一段时间,这里还是给大家推荐centos,centos很多东西是继(chao)承(xi)红帽的,可能是这个原因,所以centos很稳定、bug少。

编译步骤

编译器一般可分为预处理、编译、汇编、链接四个阶段,GNU手册也做了介绍,手册如图 1所示。

图 1

预处理:将宏定义展开,将相关和类型定义引入等操作,生成后缀为.i的预处理文件。

编译:将预处理文件编译成汇编文件,生成后缀.S的汇编文件。

汇编:将汇编文件编译成目标文件,生成后缀为.o的目标文件。

链接:将各个.o文件与相关库文件进行链接,链接方式可以选择静态或动态链接。

上面是标准的面经,同时也是网上最容易搜索到的答案,但实质根本没理解gcc/g++编译。从上述面经来看,感觉就是gcc只能编译c程序,g++只能编译c++程序。gcc/g++编译c/c++程序可以分为四种情况,gcc编译.c程序,gcc编译.cpp程序,g++编译.c程序,g++编译.cpp程序。下面通过对比这四种情况来真正了解gcc/g++编译器。

gcc/g++编译.c文件

为了彻底理解清楚两种之间的区别,下面通过编译的几个阶段去解读,test.c文件如图 2所示,这里需要注意,在test.c中我没有引入c++头文件和语法,如果用gcc编译,那么就连万里长征第一步预编译都不能通过,有且仅有当用gcc编译.c文件时,编译器才会按照C文件规则进行预编译,这里提前提出结论。为了更好的对比,对比.c文件代码中采用c规则。

图 2

预编译处理

使用gcc和g++分别对test.c进行预处理,执行结果如图 3所示。

图 3

从图中可以看到24c24等字符,c代表转换意思,前后数字代表行数,前后出现一对数字代表行号区间。同时可以看到g++预编译.c文件时候,会在部分头文件和类型定义前添加extern “C”,这个标识符的作用把标识符作用域的数据类型采用gcc去编译,C++保留了一部分过程式语言的特点(被世人称为“不彻底地面向对象”),因而它可以定义不属于任何类的全局变量和函数。但是,C++毕竟是一种面向对象的程序设计语言,为了支持函数的重载,C++对全局函数的处理方式与C有明显的不同。

编译阶段

编译阶段是把.i文件编译成汇编文件,编译过程和结果如图 4所示。

图 4

通过图中对比发现,只有程序中自定义的函数接口命中不一样,其它代码完全一样。gcc编译器编译后的函数名字和编译前函数名一致(有些可能是在函数前面添加_,具体机制是跟编译机制有关),g++编译器是在函数中添加_z3*ii。这里其它代码相同原因是程序中使用的语法c++是部分兼容c的,上图仅仅代表是一种特殊情况,因为.c文件中全部采用的c语法规则。

汇编阶段

程序处于汇编阶段时,gcc/g++内部都是调用as汇编命令,在这里两者是没有区别的,可以通过如下命令做测试,用c++_test.S做测试对比。

gcc -c c++_test.S -o c_test.o

g++ -c c++_test.S -o c++_test.o

diff c_test.o c++_test.o

通过对比试验,两个.o文件完全一样,在汇编阶段gcc/g++的作用是一样的,读者可以尽情做实验。

链接阶段

gcc/g++都是调用ld命令,同样两种区别在于传入的参数与调用库的不同,g++默认与c++库链接(兼容C语言部分,还是调用C库),gcc默认是与c库链接。实验是检验真理的最好工具,下面同样选取c++_test.o做实验。

gcc c++_test.o -o c_test

g++ c++_test.o -o c++_test

diff c_test c++_test

通过diff对比,两个可执行文件内容不一样的。通过strace跟踪系统调用结果如图 5所示。可以清晰看到两者仅仅是一些mmap地址映射不一样,即使两次用g++编译相同文件,可能生成的文件也不一样,这个不一样仅仅体现在地址映射上。

图 5

gcc/g++编译.cpp文件

编译cpp文件同样通过四个阶段做比对,同时还和编译.c文件得出的结论做对比,test.cpp文件内容如图 6所示。

图 6

复制test.cpp文件为test.c文件,然后进行四个阶段做对比。

预编译

g++ -E test.c -o test.ii

g++ -E test.cpp -o c++_test.ii

gcc -E test.cpp -o c_test.i

这里保存为.ii或者.i都是无所谓的,只有当预编译的输出需要手动指定作为编译阶段的输入(-x选项指定输入文件类型),并且没有指定编译阶段输入是什么类型文件,那么编译器就会根据系统自定义的后缀去解析,默认编译器会把.i后缀当成c预编译的结果,.ii后缀当成是c++预编译的结果。通过对比这个3个.i文件发现预编译结果完全一样,只有文件名不同,test.c与test.cpp的区别。

编译

gcc -S test.cpp -o c_test.S

g++ -S test.cpp -o c++_test.S

g++ -S test.c -o test.S

编译结果如图 7所示。生成的.S文件内容又是完全一样,只有.file不一样,这个标识符是指文件名,1c1代表第一个文件的第一行与第二个文件的第一行转换关系。

图 7

汇编

gcc -c test.cpp -o c_test.o

g++ -c test.cpp -o c++_test.o

g++ -c test.c -o test.o

汇编阶段结果同样是一致。

链接

g++ test.cpp -o c++_test

g++ test.c -o test

objdump -S test > test.obj

objdump -S c++_test > c++_test.obj

这两种编译结果通过查看二进制只有文件名是不一样的,两种方式都装载了libstdc++.so.6和libc.so.6库文件,这是g++兼容c的另外一个表现;同样可以通过反编译手段对比两个二进制文件,对比结果如图 8所示,两个obj文件同样只有文件名不一样。

图 8

还剩下一种情况没有对比,那就是gcc链接.cpp文件。

gcc c_test.o -o c_test

链接不能正常通过的,提示找不到c++库。由于链接阶段gcc不能够自动链接c++库,g++可以自动链接c++库,如果加上-lstdc++选项就能够正常编译通过。

gcc c_test.o -o c_test -lstdc++

同样可以对比c_test 与c++_test文件,但是读者会发现,这两个文件肯定不一样。我们通过反编译手段观察两个文件的区别,同样仅仅是地址不一样,比如_init地址不一样等。图 9是我截取的局部反编译对比图。程序最先从_init中rsp堆栈指针顶开始做堆栈处理,然后跳转到程序中我们看到的main函数入口地址,进入函数之前先保存栈指针,在进行push,程序中在跳转到add函数的的地址,最后程序执行完成在_fini中恢复栈平衡。(大概思路是这样的,已经三年没有碰过底层地址相关的知识,凭记忆补充一点相关知识。在嵌入式开发过程中有几个地方需要用到地址概念,uboot链接脚本确定程序第一条指令入口、编译文件顺序、位置无关地址跳转问题,栈顶设置;加载linux地址时分析相对复杂一点,编译kernel需要指定入uImage或zImage入口地址,uImage与zImage仅仅相差64Bytes头,这里牵扯到解压kernel,代码搬运等操作)。

图 9

通过上面两个对比实现可以得出如下结论:

后缀为.c的,gcc把它当成c程序;g++当作c++程序,即跟.cpp没有区别。

后缀.cpp的,gcc与g++都当成c++程序。

gcc不能自动链接c++库,g++会自动链接c++库。

c++程序中,预编译后会存在extern “C”标识符,即是用gcc按照c程序规则编译,这是兼容C程序的表现。

gcc也可以编译c++程序。

gcc编译.c文件,.c文件中一定不能出现c++语法和库操作。

__cplusplus测试

如果编译器按照c++规则编译,那么这个宏__cplusplus就会被编译器定义。上面已经得出结论了,下面通过这个宏定义再次验证上面1、2结论。test.c与test.cpp文件内容如图 10所示,依次执行如下命令。

gcc test.c && ./a.out @结果是:a+b=1314

g++ test.c && ./a.out @结果是:a+b=520

gcc test.cpp && ./a.out @结果是:a+b=520

g++ test.cpp && ./a.out @结果是:a+b=520

从结果同样可以证明,只有当用gcc编译.c程序时才会按照c规则编译程序。

图 10

有读者可能就问了,既然g++能够编译c程序,gcc还有必须要存在吗?这个答案是肯定的。原因一:操作系统全是按照c规则编写与编译(除开head.S等文件中的汇编),很多系统库文件都是按照c规则写与编译的,如果采用g++去编译这一部分,那么生成的可执行文件会非常大,以及程序运行效率大大降低;还可能存在不能正常编译通过情况,就是上述对比实验中函数链接接口不一样。编译器优化性能也是有限的,系统内核是整个上层应用的心脏,必须做到最高效率,不许存在过多冗余代码(编译器的问题)。原因二:做单片机出身的工程师对c语言扣字节操作应该是一种信仰,做上层应用的工程师更偏向c++面向对象,一个大项目基本都是通力合作完成。所以gcc用来编译c程序(效率问题,c实现对系统接口二次封装),g++编译c++程序。

工程包含.c与.cpp文件如何处理

如果是工程师自己写编译规则,那么在Makefile中应该检测.c和.cpp文件分别用gcc与g++编译,最后统一链接。如果是IDE环境,由IDE环境决定,在qt中qmake是将.c文件用gcc编译,g++编译。那么g++如何调用c程序封装的函数或者库呢,从上述讲解知识可以看到c++程序直接调用c程序接口,这个肯定报错提示找不到库函数,c和c++处理函数接口机制不一样,所以在c++程序中调用c程序应该在函数声明前加上extern “C”,这是在提醒g++编译链接这个函数时按照c函数机制去链接。同样如果在程序中函数实体前加extern “C”,这是在提醒编译器整个函数用gcc按照C规则去编译。切记理解编译与链接是两码事情。

图 11是一个QT工程模板,图中pcie.c文件的后缀只能用.c,如果换成.cpp,无论你是用gcc还是g++,走到链接阶段是找不到libpci.so提供的库函数的,虽然可以用把标准头文件路径pci.h中使用的函数声明前重新加上extern “C”,但是得不偿失。定义成.c文件qt环境会用gcc去编译,在pcie.h文件中的声明函数前加上extern “C”就可以正常链接。

图 11

动态库封装

看3条简单命令就可以很好理解,封库大多数是针对客户做二次开发使用;还有可能各个部门之间的合作需要封库。还有一种比较恶心的人,写代码特别喜欢封装库,玩隐蔽,不可替代性;在svn上只看得到几行画蛇添足的代码,在代码中调用库、管道接口、二进制文件。这种代码可阅读性很差,仅限本人阅读。

gcc -fPIC –shared test.c –o libtest.so //封库

gcc main.c –L. -ltest –o main //使用

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

---------------------

作者:HeroKern

原文:
https://blog.csdn.net/qq_21792169/article/details/85097822

 

 

原创 大财可富司机

海水潮起潮落,股市有涨有跌,入市的韭菜每年都在不断更迭,但写股票的博主来来回回也就那么些人。

前段时间有读者在后台留言,想让司机扒一下中金在线“头牌”博主天赢居。当时司机就觉得这个名字相当耳熟,后来看了相关资料才知道,早在N年前司机就曾在新浪博客看过他的文章,只是没想到,这么多年来他还在写。看来,割韭菜也是会上瘾的

那还是“带头大哥777”的时代,当年叱咤风云的财经大V,因为涉嫌非法经营罪,于2007年被逮捕。

就在“带头大哥777”消失于江湖之际,新版带头大哥再现江湖,他就是“tyj天赢居”。

青出于蓝而胜于蓝。“tyj天赢居”势头比带头大哥更猛,他在新浪、网易、东方财富网、中金等主要财经网站都开设博客。当年,东方财富网的点击数甚至超过2000万,即使每篇文章还要付费阅读,但粉丝还是积极掏钱。有媒体对此进行了报道:

如今的“tyj天赢居”主战场在中金在线,号称中金在线第一圈主,粉丝1万,2006篇文章,12亿阅读。他的微博粉丝15W、微信公众号“天赢居”每篇文章阅读量约2W。

“tyj天赢居”个人简介显示,他出生于1973年,20岁(1993年)开始炒股,在遭受股市毒打后,2006年形成自己独立的炒股体系,2007年开始在博客发布文章。他的文章主要是以技术分析为基础,对股市进行预测。

预测的准确率如何?司机以2022年以来的部分文章为例,进行分析:

1月4日,他在文章《属水的板块大涨特涨》中写道:“日线虽然不好看,但毕竟在均线密集区之上,周线、月线也在均线上方,趋势方面是在逐步走出底部区域的状态当中。底部结构成型后趋势就将向上发散,春季行情的第三浪上涨周期正在加载当中,第四次冲击大横盘箱顶趋势线的时间不远了。持股享受春季行情的红利。”

1月11日,他在文章《悬在头顶的最后一跌》中写道:“下个交易日就是调整21个交易日的节点;空间3547与233日均线共振支撑,下跌空间很小。指数已经到达底部区域,即便出现最后一跌,惯性下挫也是机会大于风险。

2月28日,他在文章《三月机会多》中写道:“目前在89周均线3456附近横盘爬升到第五周,上方55周均线和34周均线以及21周均线与13周均线粘合在3535-3555附近难以逾越,而下方144周均线3255的支撑也更为强大。所以周线即将选择方向,跌下去就可以抄底,站稳3535也可以把握新的机会。”

实际走势,大家也看到了,大盘从开年就开始下跌,一直跌到4月份的2863点才见底。他的上述预测可以说是完全错误

此外,他今年以来还有这些预测,也被证实是错误的

要说他的预测完全不准确吧,倒也不全是,比如年初他曾预测到4月27日这个重要的时间变盘点。

可是,如果股民每一次操作都完全跟着他的预测来,估计血本无本了。

预测真的只是一个概率的游戏。有些人乐此不疲,更想不通的是,还有很多人就好这一口。

“天赢居”很早开通了付费圈子,2020年付费圈子一年的订阅费用就达到7000多元,今年还要全面涨价

关于天赢居的水平如何?网上有不少讨伐他的文章,时间跨度很长,说明多年来,他始终奋战在第一线,从未懈怠。

一直以来,天赢居的身份都很神秘。网上公开信息也仅仅显示他是重庆人,毕业于重庆大学。之前他呼吁网友救助贫困学生,提供银行账号叫大家打款是“谢XX”的账号,有记者发现他的新浪博客名也为“谢XX的博客”。便误认为他姓谢。

但是,天赢居曾说过,“tyj是真实名字的缩写”。

司机通过线索梳理、层层查找,终于找出了他的真实身份。

天赢居微信公众号的帐号主体是“沙坪坝区众富商务信息咨询信息服务部”。

天眼查显示,这家公司成立于2017年,注册资本1万元,经营范围是商务信息咨询。公司经营者为唐良华。唐良华同时还是重庆朗顺投资咨询有限公司(吊销,未注销)的股东,朗顺投资的大股东名叫唐渝江

“唐渝江”的拼音缩写也是“tyj”。因此,司机很肯定,唐渝江就是天赢居的真实姓名。

此前,天赢居通过博客、网站进行股市预测,提供咨询,有投资者质疑他和“带头大哥777”一样,有非法经营罪的嫌疑

混迹于江湖多年的天赢居,也肯定知道这样做的风险。于是,他通过巧妙的办法规避了这一问题。通过挂靠投顾公司,持证上岗,这样就名正言顺,可以愉快地继续割韭菜了!

https://www.haobaiyou.com

上一篇:炒股软件免费版跟十大炒股app

下一篇:股票601288与新浪股票首页

相关推荐

返回顶部