C与C++
文章平均质量分 86
C
passenger12234
这个作者很懒,什么都没留下…
展开
-
C++: multiple and virtual inheritance under the hood
前两天跑llvm的时候遇到了有关RTTI的链接报错,借此重新回来看下C++的多继承相关的东西。希望通过本文能够把多继承和虚继承的机制解释明白。以及以下的C++术语本文的内容主要基于,建议大概阅读一遍之后再继续看下面的内容。原创 2022-11-14 19:55:39 · 759 阅读 · 1 评论 -
opt: undefined symbol when load
跟着教程写第一个llvm pass的时候,在opt load动态库的时候遇到了下面的报错报错的原因是动态链接器没有找到这个类的定义。为了理解这个类,我们需要一些背景。原创 2022-11-12 11:03:23 · 655 阅读 · 0 评论 -
动手调试C库-2 --musl-c的动态链接器
0. 序本篇承接上一篇的动手调试C库-1 ,主要讨论musl-c的动态链接器。3. overviewmusl-c的动态链接器代码主要位于ldso/dlstart.c, ldso/dynlink.c。musl-c的动态链接器重定位主要分为三个阶段,第一阶段是_dlstart_c函数,第二阶段是__dls2和__dls2b函数,第三个阶段是__dls3函数。描述动态库的数据结构是dso, 在dynlink.c中维护了四个重要的全局链表。第一个链表是关于动态库的全局加载序。static dso* he原创 2022-04-20 14:49:05 · 2495 阅读 · 0 评论 -
动手调试C库-1 程序员的自我修养第11章笔记
0. 序在我的观感上来说吧,这11章写得真是灾难。灾难体现在两个地方,一个讲的实现机制比较古老了,比如.ctor段这些gcc早已经不再使用了。另一个是glibc和windows的MSVC混着讲,看着挺不舒服的(也许是因为我把前面讲windows的地方都跳过了)。为了更实际地看看C库与C编译器是如何配合,完成C代码的初始化与运行的,尝试编译一个带调试信息的C库,手动调试是一个不错的选择。1. 从源码编译C库比较了几种C库的实现,最终选择了riscv-musl,选riscv主要是因为这个体系结构比较新,原创 2022-04-04 20:25:26 · 4660 阅读 · 0 评论 -
动态链接5 程序员的自我修养第八章笔记
0.序本文承接上一篇动态链接4,这应该是关于动态链接笔记的最后一篇了。略去了书上关于符号版本的讨论。10. linux下的动态库管理通常linux下动态库遵循命名规则libname.so.x.y.z,该动态库对应的SONAME是libname.so.x,链接时使用-lname, 比如我机器上的/usr/lib/libpcap.so.1.10.1,它的SONAME则是libpcap.so.1。链接时使用参数-lpcap。因此根据上述规则,主版本号不同的动态库对应的 SONAME也不同。这主要是因为主版本原创 2022-03-29 20:39:13 · 6170 阅读 · 0 评论 -
动态链接4 程序员的自我修养第八章笔记
0. 序本文承接上一篇动态链接36. .dynamic section.dynamic节是为动态链接器提供必要的链接信息(例如在RELRO中提到的DT_FLAGS指示动态链接器进行立即重定位),具体.dynmaic节的格式可以参考dynamic section。下面列出一些接下来讨论动态库搜索时会用到的一些.dynamic节的表项。DT_SONAME项,仅在动态库中出现,内容是一个数字表示在.dynstr中的偏移,表示该动态库的SONAME(接下来会解释这个的作用)DT_NEEDED项,内容是一原创 2022-03-29 13:19:07 · 5765 阅读 · 0 评论 -
动态链接3 程序员的自我修养第七章笔记
0. 序本篇文章承接上一篇动态链接25. Relocation Read-Only (RELRO)细心的读者如果自己尝试编译一下,会发现一个奇怪的现象,可执行文件中并没有.got.plt节,只有一个.got节。而且可执行文件中的重定位条目不会延迟绑定。一个stackoverflow的帖子讨论了这个原因。基本的出发点在于,.got.plt表存放函数的跳转地址,而且是可写的,这件事十分的危险,因此引入了Relocation Read-Only机制来保证.got.plt, .got表的只读性质。具体来说原创 2022-03-12 18:41:44 · 443 阅读 · 0 评论 -
动态链接2 程序员的自我修养第七章笔记
0. 序本篇文章承接上一篇动态链接13. 全局符号介入单靠上面的解释, 读者可能会有疑惑,既然数据a, p和printf语句在模块内部的相对地址是不变的,为什么不直接用相对pc的寻址方式拿到a, p地址呢,而非要借助.got表来绕一下弯子呢?这其实涉及到一个全局符号介入(global symbol interpose)的问题。在静态链接中,我们不允许符号冲突。但是在动态链接中,默认是允许的(也可以修改链接参数改变链接器这一行为)。以之前的weakref.c文件为基础,再引入下面的havea.c文件原创 2022-03-12 18:17:13 · 4436 阅读 · 0 评论 -
动态链接1 程序员的自我修养第七章笔记
0. 序预计这篇文章会很长,折腾了挺长时间才差不多捋清楚,主要书上一些地方和现在的实现有一点出入。1. 概览与动态链接有关系的节大概有这样一些,.interp, .dynamic, .gnu.hash, .rela.dyn, .rela.plt, .plt, .plt.got, .got, .got.plt。其中.rela.dyn和.rela.plt也可能替换为.rel.dyn, .rel.plt,取决于具体重定位类型的选择。其中.interp, .dynamic提供动态链接的一些初始信息。 .gn原创 2022-03-12 16:18:31 · 590 阅读 · 0 评论 -
弱符号与弱引用 -> 程序员的自我修养 第3,4章笔记
1. 在程序中声明并使用节名先看下面一段有意思的程序#include <stdio.h>__attribute__((section("abcd"))) int sss = 3;static int y = 1;extern int abcd;int add(int a, int b){ return a + b;}int main(){ printf("%d\n", add(sss, y)); printf("abcd %p, sss %p\n", &abc原创 2022-03-08 17:24:30 · 314 阅读 · 0 评论 -
C++11的initializer_list
0. 序今天写一道OJ的时候,发现死活超时,后来对比答案发现是因为我用了初始化列表导致超时了。因此写一篇博客记录一下。1. 花括号统一初始化一个容易混淆的概念,花括号初始化与initializer_list类。在effective modern C++中item 7详细阐述了这一点。之前一个郁闷的报错是Widget w(); Widget w{};希望初始化一个没有参数的构造函数时,第一种初始化方法会报错,因为gcc会认为这是在声明一个函数。通常在花括号初始化对象时,并不代表一定会产生相应原创 2021-12-25 19:09:16 · 727 阅读 · 0 评论 -
从一个riscv的模拟器说起
0. 序原创 2021-10-15 21:08:01 · 1130 阅读 · 0 评论 -
C++ namespace和多文件编程的笔记
1. 头文件.h和源文件.cpp从C++源代码文件到最终的可执行文件大概编译器大概做了两件事:编译和链接 。#include 用于将头文件嵌入源文件中(我目前的理解就是把头文件的内容直接拷贝到#include这个地方),这个事是在编译前完成的。随后对每个源文件进行编译,并通过链接器把这些编译后得到的目标代码合并起来,并加入库代码和启动代码(这个过程就是链接),得到最终的可执行文件。2.使用头文件和源文件的一般规则- 普通函数在编译期间,编译器只会检查函数的声明,而不会检查函数是否有定义,因此往原创 2020-06-23 16:57:58 · 711 阅读 · 0 评论 -
数算记录->二叉树->huffman树与穿线二叉树
数算记录->二叉树->huffman树1丶应用背景:在字符编码中,采取变长编码的方式能够比固定长度的编码更加省空间,为了解读的唯一性,要求任意一个字符的编码不能是另一个字符的编码的前缀。Huffman树给出了求解最优变长编码方式的方法。我们设字符d0,d1,⋯ ,dnd_0,d_1,\cdots,d_nd0,d1,⋯,dn在文本中出现的频率为k0,k1,⋯ ,knk_0,k_1,\cdots,k_nk0,k1,⋯,kn,并设最终每个字符的编码长度分别为s0,s1⋯ ,sns_0,s原创 2020-10-23 20:18:04 · 408 阅读 · 0 评论 -
C++和Python类继承中的成员隐藏和覆盖特点比较
之前在看一篇有关C++ static关键字的总结的文章的时候,这篇文章谈到在派生类会继承基类的静态成员变量,并与之共享。可以在派生类中定义重名的成员变量来屏蔽派生类对基类静态成员变量的影响。 对这句话蛮疑惑的,然后敲了一段代码试了一下。using namespace std;#include <iostream>class A {public: static int x; int y = 1; //给成员变量设置默认值,会在接下来的代码中用到 void g()原创 2020-06-24 14:13:45 · 370 阅读 · 0 评论