Comments (5)
首先因为支持32位和64位,在64位时定义了#define int int64_t,也就是说无论Windows还是Unix其实int和指针都是一个大小,32位环境中就是32位,64位环境中就是64位。和标准其实并不一样,只是为了实现方便。
然后,因为在基础版本jatcc.c中只支持char、enum、int以及他们的指针类型,而enum简单等同于int,指针和int大小相同都是sizeof(int)。考虑表达式++x:现在只有两种情况,x是char、enum、int、char*就加1,也就是sizeof(char),而x是int*
, char**
, int***
之类非char*
的指针类型都是加sizeof(int)。因为CHAR值为0,而指针复合类型就是在基础类型之上每一层指针加上一个PTR,所以char *
的类型就等于PTR,所以条件是>PTR。这里确实会比较令人费解。
简单来说这是因为只支持了这几个类型才可以这样做,在支持了union和struct之后就不能这样了,就需要取他们的单元的大小,见https://github.com/tch0/JustAToyCCompiler/blob/master/jatccex.c#L917
具体的汇编就比较简单了,可以自己分析。
from justatoyccompiler.
谢谢,x是char、enum、int、char*就加1
和因为CHAR值为0,而指针复合类型就是在基础类型之上每一层指针加上一个PTR,所以char *的类型就等于PTR,所以条件是>PTR。
我已经理解了。
但还是有点问题。对于 int *x
而言,++x
即取 x
指针紧接着的下一个指针,那它不同样是加一吗?为什么要加 sizeof(int)
?而且在c语言中,+sizeof(int)
也不能正常工作。我是不是遗漏了什么?
#include <stdio.h>
#include <stdlib.h>
int main() {
int *x, *y;
x = malloc(1024);
y = x;
*x = 1;
*++x = 2;
*++x = 3;
*++x = 4;
*++x = 5;
*++x = 6;
*++x = 7;
*++x = 8;
printf("%d %d", *y, *(y+sizeof(int)));
// 输出:1 5
}
from justatoyccompiler.
你可能没有绕过这个弯来,指针中保存的是地址,对于int* x
,++x
是移动到到下一个指针,那么指针的值(就是那个地址)就是加了sizeof(int),C语言提供了这个机制,而现在是由我们来实现这个机制。如果是x+sizeof(int)
,那不是移动到下一个元素,而是移动到后面第sizeof(int)
个元素,它的值(地址)是x
的值加上sizeof(int)*sizeof(int)
。
#include <stdio.h>
int main(int argc, char const *argv[])
{
int x[10];
printf("%p %p\n", x, x+1);
return 0;
}
示例输出:
0x7ffdfdf93440 0x7ffdfdf93444
from justatoyccompiler.
说得更清楚一点,无论什么指令集体系结构,在汇编、机器码这个层面,都是没有类型的概念的(这里的极简指令集同样),有的只有操作1字节、2字节、四字节、八字节、字、双字、四字等大小的指令,对于机器来说,没有任何手段来区分一个地址或者一个整数。C语言中指针的算术运算和算术类型不一样,指针的运算需要乘以基础类型大小,这是C语言提供的语法糖,也是需要编译器来做的事情,我们正是在做这个事情。
比如x86-64架构:
int* test(int* p)
{
return p + 1;
}
汇编:
test:
.LFB12:
.cfi_startproc
leaq 4(%rdi), %rax
ret
leaq 4(%rdi), %rax
就是对传入的值加4,然后作为返回值。在这个上下文中你无法判断这到底是一个整数还是一个指针。
你如果编一下下面这个函数,你会发现他们的汇编是完全相同的(在64位下):
int64_t test(int64_t x)
{
return x + 4;
}
from justatoyccompiler.
我明白了,加一只会让指针到下一个字节,而不是下一个整数。谢谢兄弟,祝你新年快乐!
from justatoyccompiler.
Related Issues (2)
- 请教一下,该框架下可以实现变量声明的时候初始化吗 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from justatoyccompiler.