编译生成C代码

编译器本质上就是一门语言生成另一门语言的过程

V目前的编译思路是:编译生成对应的C代码,然后调用C编译器来生成可执行文件

V语言的开发重点在编译器前端,C就是编译器后端

现在也生成了js代码,估计也会生成wasm代码

或者考虑基于LLVM,生成LLVM IR

或者直接生成机器码


生成C代码

使用-o参数就可以

把当前目录的main.v代码生成main.c代码:

1. v -o main.c ./main.v

通过查看V代码生成的C代码,可以更容易理解V编译器是如何编译的

基本类型对应

v的基本类型通过C的类型别名typedef来实现

1. //int类型没有类型别名,直接就是C的int类型
2. typedef int64_t i64;
3. typedef int16_t i16;
4. typedef int8_t i8;

6. typedef uint64_t u64;
7. typedef uint32_t u32;
8. typedef uint16_t u16;
9. typedef uint8_t byte;

11. typedef uint32_t rune;

13. typedef float f32;
14. typedef double f64;

16. typedef unsigned char* &byte; //字节指针
17. typedef int* intptr; //整型指针
18. typedef void* voidptr; //通用指针
19. typedef char* charptr; //C字符指针

21. typedef struct array array;
22. typedef struct map map;

24. typedef array array_string;
25. typedef array array_int;
26. typedef array array_byte;
27. typedef array array_f32;
28. typedef array array_f64;
29. typedef array array_u16;
30. typedef array array_u32;
31. typedef array array_u64;
32. typedef map map_int;
33. typedef map map_string;
34. typedef byte array_fixed_byte_300 [300];
35. typedef byte array_fixed_byte_400 [400];

37. typedef uint8_t byte;
38. ...
39. #ifndef bool
40. typedef int bool; //布尔类型在C里面通过int类型来实现,1字节
41. typedef byte bool;
42. #define true 1 //true是整数常量1
43. #define false 0 //false是整数常量0
44. #endif

代码对照表

常量

int类型常量,生成C的宏定义:

1. //V代码
2. const (
3. i=1 //int类型的常量
4. )

6. //C代码
7. #define _const_i 1 //整数类型的常量通过C宏定义

其他类型常量,生成C的全局变量,常量的不可修改,由V编译器负责检查

这样就很好理解,V语言中的常量可以是任何类型,跟变量一样,甚至可以是函数调用的结果

1. //V代码
2. const (
3. a=i8(11)
4. b=i16(12)
5. c=i64(13)
6. d=byte(14)
7. e=u16(15)
8. f=u32(16)
9. g=u64(17)
10. h=f32(1.1)
11. i=f64(1.2)
12. bb=true
13. )
14. //C代码
15. i8 _const_a; // inited later
16. i16 _const_b; // inited later
17. i64 _const_c; // inited later
18. byte _const_d; // inited later
19. u16 _const_e; // inited later
20. u32 _const_f; // inited later
21. u64 _const_g; // inited later
22. f32 _const_h; // inited later
23. f64 _const_i; // inited later
24. bool _const_bb; // inited later

26. void _vinit() { //然后在_vinit函数进行初始化
27. _const_a = ((i8)(11));
28. _const_b = ((i16)(12));
29. _const_c = ((i64)(13));
30. _const_d = ((byte)(14));
31. _const_e = ((u16)(15));
32. _const_f = ((u32)(16));
33. _const_g = ((u64)(17));
34. _const_h = ((f32)(1.1));
35. _const_i = ((f64)(1.2));
36. _const_bb = true;
37. }

枚举

1. //V代码
2. pub enum Color {
3. blue =1            //如果没有指定初始值,默认从0开始,然后往下递增1
4. green
5. white
6. black
7. }
8. c := Color.blue

10. //C代码
11. typedef enum {
12. Color_blue = 1 ,
13. Color_green, // 1
14. Color_white, // 2
15. Color_black, // 3
16. } Color;

18. Color c = Color_blue;

模块

V的模块,在生成对应C代码后,只是对应元素名称的前缀,毕竟C语言中没有模块的概念

常量,结构体,接口,类型等一级元素生成C代码后的名称规则是:”模块名__名称”,用双下划线区隔

模块中的add()函数生成C代码后的名称为:mymodule__add()

结构体的方法等二级元素生成C代码后的名称规则是:”模块名 _ 类名 方法名”,用单下划线区隔

例模块中的Color结构体的str()方法生成C代码后的名称为:mymodule__Color_str()

函数

主模块中的主函数和函数,生成等价的C的函数

1. //V代码
2. module main
3. fn main() {
4. println('from main')
5. add(1,3)
6. }

8. pub fn add(x,y int) int { //pub的模块访问控制由V编译器负责检查,C没有pub的对应
9. if x>0 {
10. return x+y
11. } else {
12. return x+y
13. }
14. }

16. //C代码
17. int add(int x, int y); //函数声明

19. int main(int ___argc, char** ___argv) {  //主函数生成主函数
20. _vinit(); //先执行初始化函数
21. println(tos3("from main"));
22. add(1, 3);
23. return 0;
24. }

26. int add(int x, int y) {
27. if (x > 0) {
28. return x + y;
29. } else {
30. return x + y;
31. }
32. }

函数defer语句

C没有defer语句,V编译的时候就是把函数中的defer语句去掉,然后按后进先出的顺序放在defer语句之后的所有return语句前以及函数末尾,有各自独立的代码块

1. //V代码
2. fn main(){
3. defer {defer_fn1()}
4. defer {defer_fn2()}
5. println('main start')
6. if 1<2 {
7. return
8. }
9. if 1==1 {
10. return
11. }

13. println('main end')
14. }

16. fn defer_fn1(){
17. println('from defer_fn1')
18. }

20. fn defer_fn2(){
21. println('from defer_fn2')
22. }
23. //C代码
24. int main(int ___argc, char** ___argv) {
25. _vinit();
26. println(tos3("main start"));
27. if (1 < 2) {
28. // defer
29. defer_fn1();//defer语句之后的所有return语句之前
30. // defer
31. defer_fn2();//defer语句之后的所有return语句之前
32. return 0;
33. }
34. if (1 == 1) {
35. // defer
36. defer_fn1();//defer语句之后的所有return语句之前
37. // defer
38. defer_fn2();//defer语句之后的所有return语句之前
39. return 0;
40. }
41. println(tos3("main end"));
42. // defer
43. defer_fn1();//函数末尾
44. // defer
45. defer_fn2();//函数末尾
46. return 0;
47. }

49. void defer_fn1() {
50. println(tos3("from defer_fn1"));
51. }

53. void defer_fn2() {
54. println(tos3("from defer_fn2"));
55. }

函数不确定个数参数

不确定参数就是根据返回值的类型和调用的最大参数数量,编译时动态生成一个结构体

然后把最后一个参数变为这个结构体的指针类型

不确定参数结构体,会重用,如果有别的函数也是返回了相同类型的不确定参数,会直接使用,同时修改args数组的长度为调用过参数的最大值

1. //V代码
2. fn my_fn(i int,s string, others ...string) {
3. println(i)
4. println(s)
5. println(others[0])
6. println(others[1])
7. println(others[2])
8. }

10. fn main() {
11. my_fn(1,'abc','de','fg','hi')
12. }
13. //C代码
14. struct varg_string { //自动生成不确定参数结构体
15. int len;
16. string args[4];
17. };

19. void main__my_fn(int i, string s, varg_string *others) {
20. printf("%d\n", i);
21. println(s);
22. println(others->args[0]);
23. println(others->args[1]);
24. println(others->args[2]);
25. }

27. void main__main() {
28. main__my_fn(
29. 1, tos3("abc"),
30. &(varg_string){.len = 3, .args = {tos3("de"), tos3("fg"),                 tos3("hi")}});
31. }

函数多返回值

C的函数返回值只有1个,V的函数多返回值,就是把多返回值的组合,编译时动态生成一个结构体,然后返回结构体

1. //V代码
2. fn foo() (int, int) { //多返回值
3. return 2, 3
4. }

6. fn some_multiret_fn(a int, b int) (int, int) {
7. return a+1, b+1 //可以返回表达式
8. }
9. fn main() {
10. a, b := foo()
11. println(a) // 2
12. println(b) // 3
13. }
14. //C代码
15. typedef struct _V_MulRet_int_V_int _V_MulRet_int_V_int;
16. struct _V_MulRet_int_V_int { //生成的返回值组合的结构体,还可以给其他函数共用
17. int var_0;
18. int var_1;
19. };

21. _V_MulRet_int_V_int main__foo() {
22. return (_V_MulRet_int_V_int){.var_0 = 2, .var_1 = 3};
23. }
24. _V_MulRet_int_V_int main__some_multiret_fn(int a, int b) {
25. return (_V_MulRet_int_V_int){.var_0 = a + 1, .var_1 = b + 1};
26. }
27. void main__main() {
28. _V_MulRet_int_V_int _V_mret_49_a_b = main__foo();
29. int a = _V_mret_49_a_b.var_0;
30. int b = _V_mret_49_a_b.var_1;
31. /*opt*/ printf("%d\n", a);
32. /*opt*/ printf("%d\n", b);
33. }

数组

V的数组是用struct来实现的,生成C代码也是struct

1. //V代码
2. fn main() {
3. a:=[1,3,5]
4. b:=['a','b','c']
5. println(a)
6. println(b)
7. }
8. //C代码
9. //第一部分: 从内置的vlib/built/array.v生成
10. struct array {
11. void* data;
12. int len;
13. int cap;
14. int element_size;
15. };
16. //第二部分:从内置的vlib/built/array.v生成
17. typedef struct array array;
18. typedef array array_string;
19. typedef array array_int;
20. typedef array array_byte;
21. typedef array array_f32;
22. typedef array array_f64;
23. typedef array array_u16;
24. typedef array array_u32;
25. typedef array array_u64;
26. //第三部分:数组使用的代码,字面量方式创建
27. array_int a=new_array_from_c_array(3, 3, sizeof(int), EMPTY_ARRAY_OF_ELEMS( int, 3 ) {  1 ,  3 ,  5  }) ;
28. array_string b=new_array_from_c_array(3, 3, sizeof(string), EMPTY_ARRAY_OF_ELEMS( string, 3 ) {  tos3("a") ,  tos3("b") ,  tos3("c")  }) ;
29. println (array_int_str( a ) ) ;
30. println (array_string_str( b ) ) ;
31. }

字符串

V的字符串是用struct来实现的,生成C代码也是struct

1. //V代码
2. //vlib/builtin/string.v
3. pub struct string {
4. // var:
5. // hash_cache int
6. pub:
7. str &byte // points to a C style 0 terminated string of bytes.
8. len int // the length of the .str field, excluding the ending 0 byte. It is always equal to strlen(.str).
9. }
10. //string的各种内置方法:
11. ...
12. //使用代码:
13. fn main(){
14. mystr:='abc'
15. mystr2:="def"
16. println(mystr)
17. println(mystr2)
18. }

20. //C代码
21. //第一部分:vlib/builtin/string.v生成:
22. typedef struct string string;
23. struct string {
24. byte* str;
25. int len;
26. };
27. //string的各种内置方法生成:
28. string string_left (string s, int n);
29. string string_right (string s, int n);
30. string string_substr2 (string s, int start, int _end, bool end_max);
31. string string_substr (string s, int start, int end);

33. //第二部分,使用代码:
34. void main__main () {
35. string mystr= tos3("abc") ;
36. string mystr2= tos3("def") ;
37. println ( mystr ) ;
38. println ( mystr2 ) ;
39. }

字典

V的字典是用struct来实现的,生成C代码也是struct

1. //V代码
2. //第一部分:定义map
3. pub struct map {
4. element_size int
5. root         &mapnode
6. pub:
7. size         int
8. }

10. struct mapnode {
11. left     &mapnode
12. right    &mapnode
13. is_empty bool // set by delete()
14. key      string
15. val      voidptr
16. }
17. //其他map内置方法
18. ...
19. //第二部分:使用map
20. fn main() {
21. mut m := map[string]int
22. m['one'] = 1
23. m['two'] = 2
24. println(m['one'])
25. println(m['bad_key'])
26. }

28. //C代码
29. //第一部分:定义map
30. typedef struct map map;
31. typedef struct mapnode mapnode;

33. typedef map map_int;
34. typedef map map_string;

36. struct map {
37. int element_size;
38. mapnode* root;
39. int size;
40. };
41. struct mapnode {
42. mapnode* left;
43. mapnode* right;
44. bool is_empty;
45. string key;
46. void* val;
47. };

49. //map的各种内置方法
50. ...
51. //第二部分:使用map:
52. void main__main () {
53. map_int m= new_map(1, sizeof(int)) ;
54. map_set(& m , tos3("one") , & (int []) {  1 }) ;
55. map_set(& m , tos3("two") , & (int []) {  2 }) ;
56. int tmp1 = 0; bool tmp2 = map_get(m , tos3("one"), & tmp1);

58. printf ("%d\n",  tmp1 ) ;
59. int tmp3 = 0; bool tmp4 = map_get(m , tos3("bad_key"), & tmp3);

61. printf ("%d\n",  tmp3 ) ;
62. }

结构体

生成对应的C结构体

1. //V代码
2. pub struct Point {
3. x int
4. y int
5. }

7. pub fn (p Point) str() string {
8. return 'x is ${p.x},y is:${p.y}'
9. }

11. fn main() {
12. p := Point{
13. x: 1
14. y: 3
15. }
16. println(p)
17. }

19. //C代码
20. struct Point {
21. int x;
22. int y;
23. };
24. string Point_str (Point p); //函数声明

26. string Point_str (Point p) { //函数定义,默认第一个参数是自己
27. return  _STR("x is %d,y is:%d", p .x, p .y) ;
28. }
29. void main__main () {
30. Point p= (Point) { .x =  1 , .y =  3 } ;
31. println (Point_str( p ) ) ;
32. }

结构体方法

生成对应的C函数,默认第一个参数是对应的结构体类型的指针

生成的C函数的命名规则是:”结构体名_方法名”

1. //V代码
2. pub fn (mut a array) insert(i int, val voidptr) {
3. if i < 0 || i > a.len {
4. panic('array.insert: index out of range (i == $i, a.len == $a.len)')
5. }
6. a.ensure_cap(a.len + 1)
7. size := a.element_size
8. C.memmove(a.data + (i + 1) * size, a.data + i * size, (a.len - i) * size)
9. C.memcpy(a.data + i * size, val, size)
10. a.len++
11. }
12. //C代码
13. void array_insert(array *a, int i, void *val) { //默认第一个参数是对应类型指针
14. if (i < 0 || i > a->len) {
15. v_panic(_STR("array.insert: index out of range (i == %d, a.len == %d)", i,
16. a->len));
17. };
18. array_ensure_cap(a, a->len + 1);
19. int size = a->element_size;
20. memmove((byte *)a->data + (i + 1) * size, (byte *)a->data + i * size,
21. (a->len - i) * size);
22. memcpy((byte *)a->data + i * size, val, size);
23. a->len++;
24. }

结构体访问控制

访问控制在C代码中没有体现,全部在V编译器中控制

1. //V代码
2. struct Foo {
3. a int     //私有,不可变(默认).在模块内部可访问,不可修改;模块外不可访问,不可修改
4. mut:
5. b int     // 私有,可变.在模块内部可访问,可修改,模块外部不可访问,不可修改
6. c int     // (相同访问控制的字段可以放在一起)
7. pub:
8. d int   // 公共,不可变,只读.在模块内部和外部都可以访问,但是不可修改
9. pub mut:
10. e int  //公共,模块内部可访问,可修改;模块外部可访问,但是不可修改
11. __global:
12. f int // 全局字段,模块内部和外部都可访问,可修改,这样等于破坏了封装性,不推荐使用
13. }

15. fn main() {
16. f:=Foo{}
17. println(f)
18. }

20. //C代码
21. typedef struct Foo Foo;
22. struct Foo {
23. int a;
24. int b;
25. int c;
26. int d;
27. int e;
28. int f;
29. };
30. string Foo_str();
31. void main__main() {
32. Foo f = (Foo){.a = 0, .b = 0, .c = 0, .d = 0, .e = 0, .f = 0};
33. println(Foo_str(f));
34. }
35. string Foo_str(Foo a) {
36. return _STR("{\n    a: %d\n    b: %d\n    c: %d\n    d: %d\n    e: %d\n    f: %d\n}", a.a,a.b, a.c, a.d, a.e, a.f);
37. }

流程控制语句

if语句,生成C if语句

1. //V代码
2. fn main() {
3. a := 10
4. b := 20
5. if a < b {
6. println('$a < $b')
7. }
8. else if a > b {
9. println('$a > $b')
10. }
11. else {
12. println('$a == $b')
13. }
14. }

16. //C代码
17. void main__main () {
18. int a= 10 ;
19. int b= 20 ;
20. if ( a < b ) {
21. printf( "%d < %d\n", a, b ) ;
22. }
23. else  if ( a > b ) {
24. printf( "%d > %d\n", a, b ) ;
25. }
26. else {
27. printf( "%d == %d\n", a, b ) ;
28. }

if表达式语句,生成C的三元运算符 ? :

1. //V代码
2. fn main() {
3. num := 777
4. s := if num % 2 == 0 {
5. 'even'
6. }
7. else {
8. 'odd'
9. }
10. println(s) // "odd"
11. }
12. //C代码
13. void main__main() {
14. int num = 777;
15. string s = ((num % 2 == 0) ? (tos3("even")) : (tos3("odd")));
16. println(s);
17. }

match语句

1. //V代码
2. fn main() {
3. os:='macos'
4. match os {
5. 'windows' {
6. println('windows')
7. }
8. 'linux' {
9. println('linux')
10. }
11. 'macos' {
12. println('macos')
13. }
14. else  {
15. println('unknow')
16. }
17. }
18. }
19. //C代码
20. void main__main() {
21. string os = tos3("macos");
22. string tmp1 = os;

24. if (string_eq(tmp1, tos3("windows"))) {
25. println(tos3("windows"));
26. } else if (string_eq(tmp1, tos3("linux"))) {
27. println(tos3("linux"));
28. } else if (string_eq(tmp1, tos3("macos"))) {
29. println(tos3("macos"));
30. } else // default:
31. {
32. println(tos3("unknow"));
33. };
34. }

match表达式语句

1. //V代码
2. fn main() {
3. os:='macos'
4. price:=match os {
5. 'windows' {
6. 100
7. }
8. 'linux' {
9. 120
10. }
11. 'macos' {
12. 150
13. }
14. else {
15. 0
16. }
17. }
18. println(price) //输出150
19. }

21. //C代码
22. //生成嵌套的三元表达式
23. void main__main() {
24. string os = tos3("macos");
25. string tmp1 = os;

27. int price = ((string_eq(tmp1, tos3("windows")))
28. ? (100)
29. : ((string_eq(tmp1, tos3("linux")))
30. ? (120)
31. : ((string_eq(tmp1, tos3("macos"))) ? (150) : (0))));
32. /*opt*/ printf("%d\n", price);
33. }

for循环

传统的:for i=0;i<100;i++ {}

1. //V代码
2. fn main() {
3. for i := 0; i < 10; i++ {
4. //跳过6
5. if i == 6 {
6. continue
7. }
8. println(i)
9. }
10. }

12. //C代码
13. void main__main() {
14. for (int i = 0; i < 10; i++) {

16. if (i == 6) {
17. continue;
18. };
19. /*opt*/ printf("%d\n", i);
20. };
21. }

替代while:for i<100 {}

1. //V代码
2. fn main() {
3. mut sum := 0
4. mut i := 0
5. for i <= 100 {
6. sum += i
7. i++
8. }
9. println(sum) // 输出"5050"
10. }
11. //C代码
12. void main__main () {
13. int sum= 0 ;
14. int i= 0 ;
15. while ( i <= 100 ) {

17. sum  +=  i ;
18. i ++ ;
19. }

无限循环:for {}

1. //V代码
2. fn main() {
3. mut num := 0
4. for {
5. num++
6. if num >= 10 {
7. break
8. }
9. }
10. println(num) // "10"
11. }
12. //C代码
13. void main__main() {
14. int num = 0;
15. while (1) {
16. num++;
17. if (num >= 10) {
18. break;
19. };
20. };
21. /*opt*/ printf("%d\n", num);
22. }

遍历:for i in xxx {}

1. //V代码
2. fn main() {
3. numbers := [1, 2, 3, 4, 5]
4. for i,num in numbers {
5. println('i:$i,num:$num')
6. }
7. }
8. //C代码
9. void main__main() {
10. array_int numbers = new_array_from_c_array(
11. 5, 5, sizeof(int), EMPTY_ARRAY_OF_ELEMS(int, 5){1, 2, 3, 4, 5});
12. array_int tmp1 = numbers;
13. for (int i = 0; i < tmp1.len; i++) {
14. int num = ((int *)tmp1.data)[i];

16. printf("i:%d,num:%d\n", i, num);
17. };
18. }

类型定义

类型定义type生成C的类型别名typedef

1. //V代码
2. pub struct Point {
3. x int
4. y int
5. }
6. type myint=int
7. type myPoint=Point

9. //C代码
10. struct Point {
11. int x;
12. int y;
13. };
14. typedef  int myint;
15. typedef  Point myPoint;

接口

1. //V代码

3. //C代码

泛型

1. //V代码

3. //C代码

错误处理

1. //V代码

3. //C代码

联合类型

1. //V代码
2. struct User {
3. name string
4. age int
5. }
6. pub fn (m &User) str() string {
7. return 'name:$m.name,age:$m.age'
8. }
9. type MySum= int|string|User //联合类型声明
10. i:=123
11. s:='abc'
12. u:=User{name:'tom',age:33}
13. mut res:=MySum{} //声明联合类型变量
14. res=i
15. res=s
16. res=u

18. pub fn add(ms MySum) {
19. match ms {
20. int {
21. println('ms is int,value is $it.str()')
22. }
23. string {
24. println('ms is string,value is $it')
25. }
26. User {
27. println('ms is User,value is $it.str()')
28. }
29. else {
30. println('unknown')
31. }
32. }
33. }

35. //C代码
36. #define SumType_int 1    // DEF2
37. #define SumType_string 2 // DEF2
38. #define SumType_User 3   // DEF2

40. typedef struct {
41. void *obj; //存储变量指针
42. int typ; //联合类型中对应的类型常量,就是上面的宏定义
43. } MySum;

46. //声明联合类型变量
47. MySum res = (MySum){EMPTY_STRUCT_INITIALIZATION};
48. //变量赋值
49. res = /*SUM TYPE CAST2*/ (MySum){.obj = memdup(&(int[]){i}, sizeof(int)),
50. .typ = SumType_int};
51. res = /*SUM TYPE CAST2*/ (MySum){.obj = memdup(&(string[]){s}, sizeof(string)), .typ = SumType_string};
52. res = /*SUM TYPE CAST2*/ (MySum){.obj = memdup(&(User[]{u},sizeof(User)),
53. .typ = SumType_User};
54. //match类型判断
55. if (tmp3.typ == SumType_int) {
56. int *it = (int *)tmp3.obj;
57. printf("res is:%.*s\n", int_str(*it).len, int_str(*it).str);
58. } else if (tmp3.typ == SumType_string) {
59. string *it = (string *)tmp3.obj;
60. printf("res is:%p\n", it);
61. } else if (tmp3.typ == SumType_User) {
62. User *it = (User *)tmp3.obj;
63. printf("res is:%.*s\n", User_str(&/* ? */ *it).len,
64. User_str(&/* ? */ *it).str);
65. } else // default:
66. {
67. println(tos3("unknown"));
68. };

运算符重载

1. //V代码

3. //C代码

条件编译

生成等价的C宏定义

1. //V代码
2. fn main() {
3. $if windows {
4. println('windows')
5. }
6. $if linux {
7. println('linux')
8. }
9. $if macos {
10. println('mac')
11. }
12. }
13. //C代码
14. VV_LOCAL_SYMBOL void main__main() {
15. #if defined(_WIN32)
16. {
17. }
18. #endif
19. #if defined(__linux__)
20. {
21. }
22. #endif
23. #if defined(__APPLE__)
24. {
25. println(tos_lit("mac"));
26. }
27. #endif
28. }
1. //V代码
2. fn main() {
3. mut x := 0
4. $if x32 {
5. println('system is 32 bit')
6. x = 1
7. }
8. $if x64 {
9. println('system is 64 bit')
10. x = 2
11. }
12. }

14. //C代码
15. void main__main() {
16. int x = 0;
17. #ifdef TARGET_IS_32BIT
18. println(tos3("system is 32 bit"));
19. x = 1;
20. #endif
21. ;
22. #ifdef TARGET_IS_64BIT
23. println(tos3("system is 64 bit"));
24. x = 2;
25. #endif
26. ;
1. //V代码
2. fn main() {
3. mut x := 0
4. $if little_endian {
5. println('system is little endian')
6. x = 1
7. }
8. $if big_endian {
9. println('system is big endian')
10. x = 2
11. }
12. }

14. //C代码
15. void main__main() {
16. int x = 0;
17. #ifdef TARGET_ORDER_IS_LITTLE
18. println(tos3("system is little endian"));
19. x = 1;
20. #endif
21. ;
22. #ifdef TARGET_ORDER_IS_BIG
23. println(tos3("system is big endian"));
24. x = 2;
25. #endif
26. ;

内联汇编代码

生成等价的C内联汇编的代码

1. //V代码
2. fn main() {
3. a := 10
4. b := 0
5. unsafe {    //unsafe代码块
6. asm {    //asm代码块,里面可以直接写汇编代码
7. "movl %1, %%eax;"
8. "movl %%eax, %0;"
9. :"=r"(b)
10. :"r"(a)
11. :"%eax"
12. }
13. }
14. println(a) //返回10
15. println(b) //返回10,直接通过汇编代码修改了b的值

17. e := 0
18. unsafe {
19. asm {
20. "movl $5, %0"
21. :"=a"(e)
22. }
23. }
24. println(e) //返回5,直接通过汇编代码修改了e的值
25. }

27. //C代码
28. void main__main() {
29. int a = 10;
30. int b = 0;
31. {
32. asm("movl %1, %%eax;"
33. "movl %%eax, %0;"
34. : "=r"(b)
35. : "r"(a)
36. : "%eax");
37. ;
38. };
39. /*opt*/ printf("%d\n", a);
40. /*opt*/ printf("%d\n", b);
41. int e = 0;
42. {
43. asm("movl $5, %0" : "=a"(e));
44. ;
45. };
46. /*opt*/ printf("%d\n", e);
47. }