AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79591978
Accepted
Newton's in-law
Newton's in-law
Asked: 2025-04-25 15:08:32 +0800 CST2025-04-25 15:08:32 +0800 CST 2025-04-25 15:08:32 +0800 CST

Os arquivos C padrão são compilados?

  • 772

Sempre que criamos um arquivo com definições de funções personalizadas, por exemplo, utils.ce seu arquivo de cabeçalho correspondente utils.hcontendo as declarações de função, preciso compilar o utils.carquivo junto com o código do driver em que estou usando, com um comando como gcc driver.c utils.c -o my_exe.

Então, qual instrução compila os arquivos C padrão, cujos arquivos de cabeçalho incluímos como stdio.h?

c
  • 5 5 respostas
  • 156 Views

5 respostas

  • Voted
  1. Best Answer
    Gerhard
    2025-04-25T19:29:17+08:002025-04-25T19:29:17+08:00

    A compilação é um processo de três etapas: pré-processamento, compilação e vinculação.

    gcc driver.c utils.c -o my_exeé uma abreviação de:

    gcc -c driver.c -o driver.o
    gcc -c utils.c -o utils.o
    ld driver.o utils.o -o my_exe
    

    Que é compilar o driver, compilar os utilitários e então vincular tudo.

    Ainda menos claro aqui é que as inclusões são copiadas para os arquivos C para compilação. Os passos a seguir dividem ainda mais para mostrar o pré-processamento que manipula o código nos arquivos de cabeçalho:

    gcc -E driver.c -o driver.i
    gcc driver.i -o driver.o
    gcc -E utils.c > utils.i
    gcc utils.i -o utils.o
    ld driver.o utils.o -o my_exe
    

    gcc driver.o utils.o -o my_exeTambém é possível alterar as bibliotecas de inclusão, por exemplo, -lmpara incluir a biblioteca matemática padrão (libm.a ou libm.so). Bibliotecas são apenas código-fonte C pré-compilado (código objeto ou .o) em um arquivo contêiner.

    As bibliotecas padrão (como em stdlib.he stdio.h) são libc.so(ou libc.a). Você não precisa vinculá-las explicitamente, mas pode fazê-lo se quiser.

    Então gcc driver.o utils.o -o my_exese tornagcc driver.o utils.o -o my_exe -lc

    Você pode pré-compilar seu código da mesma maneira para vinculação posterior:

    gcc -c utils.c -o utils.o
    ar rcs libUtils.a utils.o
    gcc driver.c -L. -lUtils -o my_exe
    
    • 4
  2. Reny Paul
    2025-04-25T15:31:55+08:002025-04-25T15:31:55+08:00

    Ao compilar, gcc driver.c utils.c -o my_exeele pulará a criação dos arquivos .o correspondentes e, como as alterações de driver.c e utils.c são necessárias na saída final, você precisa executar este comando sempre que houver alguma alteração em qualquer um desses arquivos. Como mencionado na resposta anterior, o arquivo C padrão é compilado como uma biblioteca estática ou dinâmica, e estas serão criadas pelo proprietário do pacote correspondente e estarão disponíveis para o usuário como parte de qualquer pacote do sistema operacional, por exemplo, libc-dev.
    Para evitar a compilação quando não houver modificações em um arquivo específico, você pode usar o Makefile, que cria um arquivo ".o" intermediário, algo como

    my_exe: driver.o utils.o
        gcc driver.o utils.o -o my_exe
    
    driver.o: driver.c
        gcc -c driver.c driver.o
    utils.o: utils.c
        gcc -c utils.c utils.o
    
    • 2
  3. Eric Postpischil
    2025-04-25T18:20:01+08:002025-04-25T18:20:01+08:00

    Então, qual instrução compila os arquivos C padrão, cujos arquivos de cabeçalho incluímos como stdio.h?

    Na maioria das implementações C, o código-fonte da biblioteca C padrão foi preparado para você e empacotado em arquivos de “biblioteca”.

    O código-fonte da biblioteca padrão é compilado ou montado em módulos de objetos, e esses módulos de objetos são inseridos em arquivos de biblioteca estáticos ou dinâmicos. Arquivos de biblioteca são, em grande parte, apenas coleções de módulos de objetos.

    O GCC e o Clang incluem a biblioteca padrão por padrão ao vincular. (Há algumas complicações nisso, como o fato de algumas implementações exigirem uma -lmopção adicional para incluir as rotinas matemáticas da biblioteca padrão.) O comando gccor clang(e algumas outras variantes, como g++) é, na verdade, um "front-end" que chama o compilador e/ou o montador e/ou o vinculador conforme necessário para os argumentos que você passa. Se você der a -vopção, eles mostrarão os comandos que executam, e o comando link incluirá um ou mais arquivos de biblioteca.

    • 2
  4. Hermit
    2025-04-25T19:11:44+08:002025-04-25T19:11:44+08:00

    Isso é o que acontece quando você inclui #include <stdio.h> (adiciona funções de entrada/saída como printf), para gerenciamento de memória #include <stdlib>, manipulação de strings #include <string.h>etc... você diz ao compilador para copiar as declarações para printf, scanfetc... essas funções estão nos arquivos de cabeçalho, como stdio.h, stdlibetc... o código para esses arquivos já está compilado, eles são parte da biblioteca GNU C.

    você tenta verbose onde esses arquivos estão localizados

    gcc -v your_program.c -o your_program

    a saída ficaria assim

    $ gcc -v test.c -o test.o 
    Using built-in specs. 
    COLLECT_GCC=gcc 
    COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper 
    OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa 
    OFFLOAD_TARGET_DEFAULT=1 
    Target: x86_64-linux-gnu 
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 
    Thread model: posix 
    Supported LTO compression algorithms: zlib zstd 
    gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)  
    COLLECT_GCC_OPTIONS='-v' '-o' 'test.o' '-mtune=generic' '-march=x86-64' '-dumpdir' 'test.o-' 
    /usr/libexec/gcc/x86_64-linux-gnu/13/cc1 -quiet -v -imultiarch x86_64-linux-gnu test.c -quiet -dumpdir test.o- -dumpbase test.c -dumpbase-ext .c -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccRbksbn.s
    GNU C17 (Ubuntu 13.3.0-6ubuntu2~24.04) version 13.3.0 (x86_64-linux-gnu) 
        compiled by GNU C version 13.3.0, GMP version 6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.26-GMP 
     
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 
    ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" 
    ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/include-fixed/x86_64-linux-gnu" 
    ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/include-fixed" 
    ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include" 
    #include "..." search starts here: 
    #include <...> search starts here: 
    /usr/lib/gcc/x86_64-linux-gnu/13/include
    /usr/local/include
    /usr/include/x86_64-linux-gnu
    /usr/include
    End of search list. 
    Compiler executable checksum: 38987c28e967c64056a6454abdef726e 
    COLLECT_GCC_OPTIONS='-v' '-o' 'test.o' '-mtune=generic' '-march=x86-64' '-dumpdir' 'test.o-' 
    as -v --64 -o /tmp/ccwriUWR.o /tmp/ccRbksbn.s
    GNU assembler version 2.42 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.42 
    COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/13/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/ 
    LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/13/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/13/../../../:/lib/:/usr/lib/ 
    COLLECT_GCC_OPTIONS='-v' '-o' 'test.o' '-mtune=generic' '-march=x86-64' '-dumpdir' 'test.o.' 
    /usr/libexec/gcc/x86_64-linux-gnu/13/collect2 -plugin /usr/libexec/gcc/x86_64-linux-gnu/13/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper -plugin-opt=-fresolution=/tmp/ccO6Fe7I.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o test.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/13/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/13 -L/usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/13/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/13/../../.. /tmp/ccwriUWR.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/13/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/crtn.o
    COLLECT_GCC_OPTIONS='-v' '-o' 'test.o' '-mtune=generic' '-march=x86-64' '-dumpdir' 'test.o.'
    

    aqui você pode ver três fases:

    1. Compilação de seus .carquivos em .oarquivos de objeto, por meio de chamadas para cc1e as.

    2. Vinculação desses arquivos de objeto, além dos arquivos de inicialização ( Scrt1.o, crti.o, crtn.o) e das bibliotecas de tempo de execução C pré-construídas (bibliotecas de suporte do GCC e a biblioteca padrão C).

    3. O resultado é seu executável final.

    No seu dump detalhado, a linha-chave está enterrada na invocação collect2/ ld:

    … -plugin-opt=-pass-through=-lc … -lc …

    Esse -lcé o sinalizador do vinculador que informa:

    “Puxe a biblioteca padrão C (libc), que já contém o código compilado para printf, fopen, etc.”

    Você não compila stdio.c(nem qualquer um dos .ccódigos-fonte da glibc) sozinho. A biblioteca C é fornecida como arquivos pré-compilados ( libc.a) e objetos compartilhados ( libc.so), e os drivers GCC são passados ​​automaticamente -lcem tempo de link para que todas as suas <stdio.h>declarações sejam resolvidas em código real na libc.

    uma boa leitura seria https://www.gnu.org/software/libc/manual/html_node/Header-Files.html e Como funciona o processo de compilação/vinculação?

    • 1
  5. sairaman g
    2025-04-25T19:49:32+08:002025-04-25T19:49:32+08:00

    Os arquivos C padrão já estão compilados e fazem parte da biblioteca stdc++ e de outras bibliotecas vinculadas a ela. No meu caso, estava lá em

    /usr/lib/x86_64-linux-gnu/libstdc++.so.6
    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.30.
    

    Um teste de exemplo para verificar se a .socontém uma função ou não. Acabei de verificar se printfestá presente neste libstdc++.so.6.

    readelf -a libstdc++.so.6 | grep printf
    
    000000226468  001f00000007 R_X86_64_JUMP_SLO 0000000000000000 \__fprintf_chk@GLIBC_2.3.4 + 0
    
    000000226ec0  005b00000007 R_X86_64_JUMP_SLO 0000000000000000 sprintf@GLIBC_2.2.5 + 0
    
    000000227448  007900000007 R_X86_64_JUMP_SLO 0000000000000000 vsnprintf@GLIBC_2.2.5 + 0
    
    000000227bb8  009f00000007 R_X86_64_JUMP_SLO 0000000000000000 \__sprintf_chk@GLIBC_2.3.4 + 0
    

    Cada versão do gcc tem uma versão correspondente libstdc++.so, por isso não é possível executar um executável criado com uma versão superior do gcc em uma versão inferior. Ele não possui os símbolos de tempo de execução necessários.

    • 0

relate perguntas

  • Multiplicação mais rápida que *

  • Usando uma macro para comprimento de string no especificador de formato scanf () em C

  • Como você pode definir o tipo de dados de #define para long double?

  • Ponteiros const incompatíveis

  • Mudança de cor não gradual no OpenGL

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve