分类:Tech

共 22 篇文章

Call convention & Name mangling

标题只是为了满足强迫症,文中对于 Call convention 还是使用中文翻译的调用约定,但 Name mangling 因为不知道怎么翻译好,就保持吧。

之前同学在聊面试的时候提到被问过调用约定(Call convention)相关的问题,突然想起来自己虽然知道这个东西影响的是方法调用(比如参数如何传递、调用栈清理等),但是并不记得每个类型的调用约定存在的作用以及具体内容,于是查了一下。

调用约定(Call convention)

调用约定规定了一个方法在被调用的时候需要遵循的一些内容:

  1. 参数如何传递,包括使用寄存器还是堆栈或是混合、从左到右压栈还是从右到左压栈。
  2. 调用栈最终由谁负责恢复?调用者(Caller)或被调用者(Callee)。
  3. 方法最终在链接时使用的符号名。
  4. 更多...

显然,调用约定是 ABI(Application binary interface) 层面的东西,而且这玩意有很多类型,历史原因在于以前提供机器的那波厂商没有顺带提供操作系统和编译器,而是把这两块交给了市场,于是各家自己玩自己的,弄出来各种自己的标准,所以 ABI 兼容就别想了。虽然也有如 ...

阅读全文

MS Visual Studio对C++多继承的相关实现

本文的内容来自于在VS2013中的实验,只能说明一种可行的实现途径,不代表编译器必须这样实现。后续内容中如未特殊提及,编译器代指VS2013。

首先,我们来明确一个观点:在类成员方法中,this指针是否一定要指向这个对象的内存起始处?答案是不一定,指向起始处当然是很方便我们这些脑算成员变量偏移的,因为只用做加法就行了,但是对于编译器而言,它只需要确定好一个关于this指向的原则,随后基于这个原则,不管偏移要加法还是减法,对它来说都是没什么区别的。因此,this的指向实际上是编译器自己决定的,它可以遵照常规的想法,在进入成员方法代码前,把this调整至对象内存起始,或者是为了性能,采用它自己的原则。

显然,VS这样的编译器使用的是后者,它出于性能考虑,约定了自己的原则:this指针在一个类成员方法中的指向,取决于该方法的来源。具体来说:

  • 如果该方法首次声明在本类中,那么this指向本类对象的内存起始位置。
  • 如果该方法首次声明不在本类中,即来自于父类,那么this应指向第一个声明此方法的父类,也就是多继承的情况下,在子类的视角中,顺序靠前的父类覆盖靠后的父类。

由于类成员方法是可以在继承关系中调用的,即子类对象可以调用父类的public成员方法。那么,按照这个原则中的第2条,编译器需要做一些调整工作。

下面举个例子,并结合例子来讲讲this调整的过程:

namespace base_adjust_rule ...
阅读全文

和Shadowsocks一起科学上网

拖延症晚期,本来上上个月把新机器折腾好了之后就想写这个内容的,丢到Todo里后就没理它了,今天发现还有一个更早前想写的内容至今也没开始码。 这篇东西呢,没什么干货,只是一个整理,记下如何利用Shadowsocks来科学上网,包括VPS相关的内容。因此,对于不同的VPS提供商、不同的OS可能不适用,可以自行搜索。

VPS搭建服务器

稍微讲讲VPS的选择吧,一句话,你选的VPS所在的网络必须能够访问你的目标网站,比如你想通过VPS上Google,那选阿里云你就只会一脸懵逼了。

穷人表示我用的是DigitalOcean,还是最便宜的$5一个月那种,不过也够用了,流量好像是不限制的,带宽貌似是百兆,以下简称DO。

额,毕竟不是软文也不是小白教程,就不截没必要的图了。Droplet选的Ubuntu 14.04,创建完毕后,DO会给你发邮件,里面有VPS的IP以及root用户的密码,用ssh工具(Windows下可以下载putty)连接上去进行如设置root密码等一系列基础的配置后即可:

  • *unix: ssh root@IP
  • Windows: 在putty里填写IP,然后点击连接

开启IPv6

默认的情况下DO是关闭IPv6的,可以到Droplet的管理页面中开启,系统会为VPS分配相应的IPv6地址 ...

阅读全文