.o与C中的out

.o与C中的out,c,file,output,C,File,Output,我在debian系统中使用gcc编译C代码。通常,我会使用gcc file.c-o file.out。但是我错误地键入了gcc file.c-o file.o 当,正在运行./file.o时,它仍然有效 这个.o文件是什么,它与.out相同吗?按照惯例,.o后缀是对象代码。GCC和其他编译器在编译时实际上要经过几个步骤。在高层次上,它看起来像这样**: 预处理器。这解决了#定义和#包含和其他#..宏的问题。这一步很少被输出到文件中——它几乎被普遍地直接传递到下一步 对象编译。代码行被转换成机器代

我在debian系统中使用gcc编译C代码。通常,我会使用gcc file.c-o file.out。但是我错误地键入了gcc file.c-o file.o

当,正在运行./file.o时,它仍然有效


这个.o文件是什么,它与.out相同吗?

按照惯例,
.o
后缀是
对象
代码。GCC和其他编译器在编译时实际上要经过几个步骤。在高层次上,它看起来像这样**:

  • 预处理器。这解决了
    #定义
    #包含
    和其他
    #..
    宏的问题。这一步很少被输出到文件中——它几乎被普遍地直接传递到下一步
  • 对象编译。代码行被转换成机器代码和符号表。符号表尚未链接到可执行文件中。对于较大的程序,这是在编译多个可能相互依赖的文件时的中间输出
  • 链接。目标代码中的符号现在被解析为实际的内存位置或调用点,以提供一个完全成熟的可执行文件
  • **是的,这是一个简化视图,省略了优化、调试符号、剥离、库链接和其他一些步骤,但这些也可以被视为编译过程中的子步骤

    按惯例:

    • C文件名为
      .C
      .h
    • C++:
      .cpp
      .hpp
      .C++
      .h++
    • 对象文件的名称为
      .o
    • Fortran是
      .f
    • 程序集与相同
    • 静态库在UNIX上是
      .a
      ,在Windows上是
      .lib
    • 动态库在UNIX上是
      .so
      ,在Windows上是
      .dll
    • 在Windows上,可执行文件一般不在UNIX上,也不在代码> > exe < /C>上,但对于没有指定输出名的链接C和C++程序,存在默认的<代码> .AUD/<代码>。

    上述内容没有任何理由或要求,除非这是自70年代以来所做的事情,也是程序员所期望的。

    按照惯例,
    .o
    后缀是
    对象
    代码。GCC和其他编译器在编译时实际上要经过几个步骤。在高层次上,它看起来像这样**:

  • 预处理器。这解决了
    #定义
    #包含
    和其他
    #..
    宏的问题。这一步很少被输出到文件中——它几乎被普遍地直接传递到下一步
  • 对象编译。代码行被转换成机器代码和符号表。符号表尚未链接到可执行文件中。对于较大的程序,这是在编译多个可能相互依赖的文件时的中间输出
  • 链接。目标代码中的符号现在被解析为实际的内存位置或调用点,以提供一个完全成熟的可执行文件
  • **是的,这是一个简化视图,省略了优化、调试符号、剥离、库链接和其他一些步骤,但这些也可以被视为编译过程中的子步骤

    按惯例:

    • C文件名为
      .C
      .h
    • C++:
      .cpp
      .hpp
      .C++
      .h++
    • 对象文件的名称为
      .o
    • Fortran是
      .f
    • 程序集与相同
    • 静态库在UNIX上是
      .a
      ,在Windows上是
      .lib
    • 动态库在UNIX上是
      .so
      ,在Windows上是
      .dll
    • 在Windows上,可执行文件一般不在UNIX上,也不在代码> > exe < /C>上,但对于没有指定输出名的链接C和C++程序,存在默认的<代码> .AUD/<代码>。

    上述内容没有任何理由或要求,除非这是自70年代以来所做的事情,也是程序员所期望的。

    当您调用
    gcc
    时,没有选项告诉它生成不同类型的输出(例如
    -c
    来创建对象文件
    -s
    来创建程序集文件),它将创建一个可执行文件。它会这样做,而不考虑您为该文件指定的名称和扩展名。因此,在您的例子中,
    file.o
    是一个可执行文件,与任何其他可执行文件(无论其扩展名如何)没有区别

    按照惯例,
    .o
    扩展名用于对象文件,可执行文件不应具有扩展名(即使默认名称为
    a.out
    ,具有
    .out
    扩展名,但该扩展名并不常用)。您打破了惯例,将文件命名为
    .o
    ,但是,除了令人困惑之外,这没有实际意义


    将文件命名为
    .o
    不会告诉
    gcc
    它应该创建一个对象文件。只有
    -c
    选项才能执行此操作。由于没有传递该选项,因此没有创建对象文件。

    当调用
    gcc
    时,如果没有告诉它生成不同类型输出的选项(例如
    -c
    创建对象文件
    -S
    创建程序集文件),它将创建一个可执行文件。它会这样做,而不考虑您为该文件指定的名称和扩展名。因此,在您的例子中,
    file.o
    是一个可执行文件,与任何其他可执行文件(无论其扩展名如何)没有区别

    按照惯例,
    .o
    扩展名用于对象文件,可执行文件不应具有扩展名(即使默认名称为
    a.out
    ,具有
    .out
    扩展名,但该扩展名并不常用)。您打破了惯例,将文件命名为
    .o
    ,但是,除了令人困惑之外,这没有实际意义

    命名你
    gcc -c program.c
    
    ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o program.o -lc /usr/lib/x86_64-linux-gnu/crtn.o
    
    gcc program.c
    
           If -o is not specified, the default is to put an executable file
           in a.out, the object file for source.suffix in source.o, its
           assembler file in source.s, a precompiled header file in
           source.suffix.gch, and all preprocessed C source on standard
           output.