LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1892|回复: 22

C必须包含main函数吗?

[复制链接]
发表于 2004-10-6 15:45:49 | 显示全部楼层 |阅读模式
必须吗?

C++呢?
发表于 2004-10-6 17:13:00 | 显示全部楼层
要是想编译成可执行文件就必须有。C++ 也一样。
发表于 2004-10-7 04:16:44 | 显示全部楼层
可以自己指定程序入口的,这个不是早说过了吗
发表于 2004-10-7 13:07:40 | 显示全部楼层
只用 C 怎样指定?
发表于 2004-10-7 16:40:24 | 显示全部楼层
在链接时指定。man ld可以看到这个选项:

  1. -e entry
  2.        --entry=entry
  3.            Use  entry  as  the explicit symbol for beginning execution of your
  4.            program, rather than the default entry point.  If there is no  sym-
  5.            bol  named  entry,  the linker will try to parse entry as a number,
  6.            and use that as the entry address (the number will  be  interpreted
  7.            in  base  10;  you may use a leading 0x for base 16, or a leading 0
  8.            for base 8).
复制代码
发表于 2004-10-7 17:02:46 | 显示全部楼层
最初由 kj501 发表
在链接时指定。man ld可以看到这个选项:
  1. -e entry
  2.        --entry=entry
  3.            Use  entry  as  the explicit symbol for beginning execution of your
  4.            program, rather than the default entry point.  If there is no  sym-
  5.            bol  named  entry,  the linker will try to parse entry as a number,
  6.            and use that as the entry address (the number will  be  interpreted
  7.            in  base  10;  you may use a leading 0x for base 16, or a leading 0
  8.            for base 8).
复制代码


多谢。可是我没看懂。 请你说明一下。例如,我想编译下面这个文件,以 x 代替 main,该怎样编译呢?
  1. #include <stdio.h>
  2. int x(int argc, char *argv[])
  3. {
  4.     printf("Hello, world!\n");
  5.     return 0;
  6. }
复制代码

我是这么编译的:
  1. herbert@natsu:~$ gcc -c x.c
  2. herbert@natsu:~$ ld -o x -e x /usr/lib/crti.o x.o -lc
  3. herbert@natsu:~$ ./x
  4. bash: ./x: No such file or directory
  5. herbert@natsu:~$ ls
  6. ar4  Desktop  latex  Mail  misc  pict  uv6  x  x.c  x.o
  7. herbert@natsu:~$
复制代码
发表于 2004-10-7 17:26:45 | 显示全部楼层
你的做法不对。
先用gcc编译源文件,但不链接库文件。我把源程序保存为temp.c:

  1. gcc -c temp.c -o temp.o
复制代码

这时用nm就可以看到temp.o中有x这个符号,x前面的T表示x这个符号在text段:

  1. [kj501@s2023 c]$ nm temp.o
  2.          U printf
  3. 00000000 T x
复制代码

然后再用ld来链接,生成的可执行文件为a.out。

  1. ld -e x -o a.out temp.o -lc -dynamic-linker /lib/ld-linux.so.2
复制代码

要注意此时链接的库文件必须包含标准C库文件libc(程序中使用了标准库函数printf,如果不用,可以不加)和加载动态库的/lib/ld-linux.so.2(因为libc缺省链接的是动态库)。不然是不会成功的。
链接完成后,用ldd查看,可以看到链接的动态库文件:

  1. [kj501@s2023 c]$ ldd a.out
  2.         linux-gate.so.1 =>  (0xffffe000)
  3.         libc.so.6 => /lib/tls/libc.so.6 (0x4002a000)
  4.         /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
复制代码

现在就可以运行程序了。

  1. [kj501@s2023 c]$ ./a.out
  2. Hello, world!
  3. Segmentation fault
复制代码

能出来结果,但也有段错误,是什么地方出来问题,我还没有想清楚。
发表于 2004-10-7 17:29:09 | 显示全部楼层
最初由 herberteuler 发表
herbert@natsu:~$ ./x
bash: ./x: No such file or directory

出现这个结果是因为没有链接动态库ld-linux.so.2。
发表于 2004-10-7 17:33:08 | 显示全部楼层
像这样自己指定的入口是不是没有编译器生成的一些额外指令啊?或许这就是段错误产生的原因吧。
发表于 2004-10-7 17:47:24 | 显示全部楼层
下面是手工生成的:
  1. .file   "x.c"
  2.         .section        .rodata
  3. .LC0:
  4.         .string "Hello, world!\n"
  5.         .text
  6. .globl x
  7.         .type   x, @function
  8. x:
  9.         pushl   %ebp
  10.         movl    %esp, %ebp
  11.         subl    $8, %esp
  12.         movl    $.LC0, (%esp)
  13.         call    printf
  14.         movl    $0, %eax
  15.         leave
  16.         ret
  17.         .size   x, .-x
  18.         .section        .note.GNU-stack,"",@progbits
  19.         .ident  "GCC: (GNU) 3.3.4 (Debian 1:3.3.4-13)"
复制代码

下面是自动生成的:
  1. .file   "x2.c"
  2.         .section        .rodata
  3. .LC0:
  4.         .string "Hello, world!\n"
  5.         .text
  6. .globl main
  7.         .type   main, @function
  8. main:
  9.         pushl   %ebp
  10.         movl    %esp, %ebp
  11.         subl    $8, %esp
  12.         andl    $-16, %esp
  13.         movl    $0, %eax
  14.         subl    %eax, %esp
  15.         movl    $.LC0, (%esp)
  16.         call    printf
  17.         movl    $0, %eax
  18.         leave
  19.         ret
  20.         .size   main, .-main
  21.         .section        .note.GNU-stack,"",@progbits
  22.         .ident  "GCC: (GNU) 3.3.4 (Debian 1:3.3.4-13)"
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表