zoukankan      html  css  js  c++  java
  • 【转】

    原文:http://c.biancheng.net/view/2384.html

    ——————————————————————————————————————

    编译多个源代码文件会生成多个目标文件,每个目标文件都包含一个源文件的机器码和相关数据的符号表。除非使用-c选项指示 GCC 只编译不链接,否则 GCC 会使用临时文件作为目标文件输出:

    $ gcc -c main.c
    $ gcc -c func.c

    这些命令会在当前目录中生成两个目标文件,分别是 main.o 和 func.o。把两个源文件名放在同一个 GCC 命令中,也可以获得同样的结果:

    $ gcc -c main.c func.c

    然而,实际上编译器通常每次只会被调用来完成一件小型任务。大的程序包含许多源文件,在开发期间必须被编译、测试、编辑,然后再编译,很少会有在创建中的修改行为会影响所有的源文件。为了节省时间,可以使用 make 控制创建过程,由它调用编译器重新编译,而且只编译比对应的最新源文件旧的那些目标文件。

    一旦所有当前源文件都被编译为目标文件,就可以使用 GCC 来链接它们

    $ gcc main.o func.o -o app.out -lm

    GCC 假设扩展名为.o的文件是要被链接的目标文件

    ----------____________________________________________________________________________

    GCC -S选项:生成汇编文件

    编译器的核心任务是把C程序翻译成机器的汇编语言(assembly language)。汇编语言是人类可以阅读的编程语言,也是相当接近实际机器码的语言。由此导致每种 CPU 架构都有不同的汇编语言。

    实际上,GCC 是一个适合多种 CPU 架构的编译器,不会把C程序语句直接翻译成目标机器的汇编语言,而是在输入语言和输出汇编语言之间,利用一个中间语言,称为 RegisterTransfer Language(简称 RTL,寄存器传输语言)。借助于这个抽象层,在任何背景下,编译器可以选择最经济的方式对给定的操作编码。

    而且,在交互文件中针对目标机器的抽象描述,为编译器重新定向到新架构提供了一个结构化的方式。但是,从 GCC 用户角度来看,我们可以忽略这个中间步骤。

    通常情况下,GCC 把汇编语言输出存储到临时文件中,并且在汇编器执行完后立刻删除它们。但是可以使用-S选项,让编译程序在生成汇编语言输出之后立刻停止。

    如果没有指定输出文件名,那么采用-S选项的 GCC 编译过程会为每个被编译的输入文件生成以.s作为后缀的汇编语言文件。如下例所示:

    $ gcc -S circle.c

    编译器预处理 circle.c,将其翻译成汇编语言,并将结果存储在 circle.s 文件中。

    如果想把C语言变量的名称作为汇编语言语句中的注释,可以加上-fverbose-asm选项:

    $ gcc -S -fverbose-asm circle.c

     

    ______________________________________________

    typedef 和 #define 的区别

    typedef 在表现上有时候类似于 #define,但它和宏替换之间存在一个关键性的区别。正确思考这个问题的方法就是把 typedef 看成一种彻底的“封装”类型,声明之后不能再往里面增加别的东西。

    1) 可以使用其他类型说明符对宏类型名进行扩展,但对 typedef 所定义的类型名却不能这样做。如下所示:

    #define INTERGE int
    unsigned INTERGE n;  //没问题

    typedef int INTERGE;
    unsigned INTERGE n;  //错误,不能在 INTERGE 前面添加 unsigned


    2) 在连续定义几个变量的时候,typedef 能够保证定义的所有变量均为同一类型,而 #define 则无法保证。例如:

    #define PTR_INT int *
    PTR_INT p1, p2;

    经过宏替换以后,第二行变为:

    int *p1, p2;

    这使得 p1、p2 成为不同的类型:p1 是指向 int 类型的指针,p2 是 int 类型。

    相反,在下面的代码中:

    typedef int * PTR_INT
    PTR_INT p1, p2;

    p1、p2 类型相同,它们都是指向 int 类型的指针

  • 相关阅读:
    RABBITMQ/JAVA 客户端测试(再补:利用文件流)
    在虚拟机中安装CentOS7
    RabbitMQ/JAVA 客户端测试(补:利用线程)
    ffmepg-nginx-nginx-rtmp-module配置脚本
    PDO防注入原理分析以及使用PDO的注意事项
    使用MySQL Proxy解决MySQL主从同步延迟
    好文收藏
    CentOS6.6安装mysql出现的问题
    大型网站技术架构相关文章
    Redis必要的一些配置
  • 原文地址:https://www.cnblogs.com/oxspirt/p/13876018.html
Copyright © 2011-2022 走看看