Dúvida Básica sobre bibliotecas .h

1. Dúvida Básica sobre bibliotecas .h

Apprentice X
ApprenticeX

(usa Slackware)

Enviado em 25/01/2022 - 15:23h

Bom dia a Todos

No exemplo abaixo, uso somente a função puts
O programa compilado só tira de stdio.h apenas o que usei?
Ou ele está incluindo desnecessáriamente todas as funções existentes em stdio.h mesmo que eu não esteja usando elas?
#include <stdio.h> // puts
int main(void) {
puts("test");
}

Minha dúvida é porque pensei em ter minhas próprias bibliotecas em 1 arquivo, mas seria meio disperdício de recursos ter 1 arquivo com um monte de funções para usar dele apenas 1 ou 2 no programa, o que me fez pensar não valer a pena ter um arquivo de bibliotecas para usar 1 ou 2 em um programa!


  


2. Re: Dúvida Básica sobre bibliotecas .h

Mauricio Ferrari
mauricio123

(usa Slackware)

Enviado em 29/01/2022 - 11:01h


Não creio que isso vá importar todas as funções desnecessariamente. Como programei pouco em C, não me atentei disso. Acredito que o compilador só vai incluir o que o código usa.

___________________________________________________________
Conhecimento não se Leva para o Túmulo.
https://github.com/mxnt10


3. Re: Dúvida Básica sobre bibliotecas .h

Paulo
paulo1205

(usa Ubuntu)

Enviado em 30/01/2022 - 17:33h

ApprenticeX escreveu:

Bom dia a Todos

No exemplo abaixo, uso somente a função puts
O programa compilado só tira de stdio.h apenas o que usei?
Ou ele está incluindo desnecessáriamente todas as funções existentes em stdio.h mesmo que eu não esteja usando elas?
#include <stdio.h> // puts
int main(void) {
puts("test");
}

Minha dúvida é porque pensei em ter minhas próprias bibliotecas em 1 arquivo, mas seria meio disperdício de recursos ter 1 arquivo com um monte de funções para usar dele apenas 1 ou 2 no programa, o que me fez pensar não valer a pena ter um arquivo de bibliotecas para usar 1 ou 2 em um programa!


Na verdade, a definição das funções não reside no arquivo de cabeçalhos (headers, razão pela qual o sufixo é .h). Os cabeçalhos contêm apenas as declarações de funções e variáveis globais, e definições de macros (principalmente constantes) e de tipos de dados (estruturas, uniões, enumerações e typedefs), que são informações que o compilador precisa conhecer para poder verificar o correto uso sintático e fazer substituição de valores durante a compilação.

A implementação das funções e as definições dos valores das variáveis globais normalmente reside em alguma biblioteca ou em um arquivo objeto anteriormente compilado de forma separada. É apenas no momento da ligação (linking, chamada por alguns mais antigos, como eu, de linkedição) que as funções e variáveis invocadas ou usadas por um programa são efetivamente amarradas a suas implementações, num processo que é mais ou menos equivalente a substituir todas as referências meramente simbólicas pelos endereços onde reside a implementação de cada um dos símbolos.

Então, recapitulando, os cabeçalhos declaram os símbolos, e as bibliotecas contêm suas implementações.

Dito isso, fica a pergunta de se convém colocar todos os símbolos num arquivo só de cabeçalhos, como costumava fazer o Windows com seu <windows.h>, ou se é melhor separar em vários arquivos menores, com funções mais ou menos relacionadas entre si, como faz o padrão do C ao dividir sua biblioteca <stdio.h>, <string.h>, <time.h> etc. E a resposta é a que se poderia esperar: depende, pois cada abordagem tem suas vantagens e desvantagens, e eventuais soluções de contorno para ajudar a compensar parte das desvantagens.

A principal desvantagem do “arquivão único” é que o processamento do arquivo pelo compilador toma tempo e, num programa muito grande, com milhares de arquivos fontes incluindo o mesmo cabeçalho gigantesco, tal cabeçalho enorme tem de ser reprocessado múltiplas vezes (pelo menos uma vez para cada arquivo fonte que o inclui). Nesse aspecto, reduzir a quantidade de declarações e definições de tipos de dados no arquivo é vantajoso para reduzir o esforço computacional total durante um processo de compilação muito grande. A contrapartida é que essa redução do esforço computacional implica transferir para os programadores (tanto aqueles que criam e mantêm os cabeçalhos quanto aqueles que os usam) saber o que aparece em qual cabeçalho, e incluir explicitamente todos os que forem necessários em cada arquivo que compõe o código fonte.

Por fim, voltando ao seu exemplo, se a única função que o seu programa usa da biblioteca padrão é puts(), tipicamente o linker vai evitar colocar no executável aquilo que não for necessário (por exemplo: embora scanf() e qsort() residam na mesma biblioteca que puts(), provavelmente o linker não vai incluir no executável gerado essas funções que o seu programa não emprega).


... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)


4. Re: Dúvida Básica sobre bibliotecas .h

Apprentice X
ApprenticeX

(usa Slackware)

Enviado em 07/02/2022 - 21:26h

paulo1205 escreveu: Por fim, voltando ao seu exemplo, se a única função que o seu programa usa da biblioteca padrão é puts(), tipicamente o linker vai evitar colocar no executável aquilo que não for necessário (por exemplo: embora scanf() e qsort() residam na mesma biblioteca que puts(), provavelmente o linker não vai incluir no executável gerado essas funções que o seu programa não emprega).

Obrigado Paulo por responder, porém as palavras que vc usou para a resposta são um tanto vagas :-) Vc usou tipicamente e provavelmente
A dúvida que ficou foi: Existe alguma forma de Eu saber se ele está de fato usando apenas 1 função?


5. Re: Dúvida Básica sobre bibliotecas .h

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 07/02/2022 - 21:35h


ApprenticeX escreveu:

paulo1205 escreveu: Por fim, voltando ao seu exemplo, se a única função que o seu programa usa da biblioteca padrão é puts(), tipicamente o linker vai evitar colocar no executável aquilo que não for necessário (por exemplo: embora scanf() e qsort() residam na mesma biblioteca que puts(), provavelmente o linker não vai incluir no executável gerado essas funções que o seu programa não emprega).

Obrigado Paulo por responder, porém as palavras que vc usou para a resposta são um tanto vagas :-) Vc usou tipicamente e provavelmente
A dúvida que ficou foi: Existe alguma forma de Eu saber se ele está de fato usando apenas 1 função?

Cara, não se preocupa com esse detalhe. Hoje em dia com RAM na casa dos GB, não é uma boa ideia ficar "contando byte" ou mesmo quantas funções são inseridas no exe final. Então, use os headers que precisar e não se limite por conta do header adicionar mais uns kilobytes a mais no seu executável.


6. Re: Dúvida Básica sobre bibliotecas .h

Apprentice X
ApprenticeX

(usa Slackware)

Enviado em 08/02/2022 - 22:36h

SamL escreveu:Cara, não se preocupa com esse detalhe. Hoje em dia com RAM na casa dos GB, não é uma boa ideia ficar "contando byte" ou mesmo quantas funções são inseridas no exe final. Então, use os headers que precisar e não se limite por conta do header adicionar mais uns kilobytes a mais no seu executável.

Boa Noite SamL, Obrigado pela explicação, mas não quero ficar limitado a programar apenas em PCs! Microcontroladores não tem 1Gb de RAM! Estou aprendendo C justamente para aprender a programar direito! E isso significa não disperdiçar recursos! Do contrário eu programaria em uma Linguagem de Alto Nível que é muito mais fácil! C me dá a oportunidade de entender como cada coisa é feita de verdade!

Muitos programadores qdo escrevem um texto em uma tela como ShowMessage("Hello"); não fazem idéia da quantidade de linhas de código ocultas por traz de apenas 1 comando! Logo pra mim, eu acho sim uma excelente idéia contar cada byte que um programa meu está usando, e saber também onde cada byte está sendo usado e porque! Sem disperdícios! Não é uma questão de economizar e sim uma questão de ter total controle sobre aquilo que estou escrevendo e seu funcionamento!

Dando uma outra idéia da explicação: Se eu fosse carpinteiro, não me contentaria em apenas fazer uma Mesa!
Eu ia querer ter total conhecimento da madeira, de onde ela vem, como ela é plantada, quais os tipos disponíveis e porque outros não são disponíveis, ou seja, eu estaria estudando Plantas, Vegetações, Florestas, Adubo e etc...

Estou aprendendo C, querendo aprender Assembly, pq gosto de programação, e de preferência as Bases da Programação. Quando decidi escrever minhas próprias bibliotecas substituindo: strlen, strcat, strcmp e etc... não é pra competir com elas, e sim para entender como elas funcionam, como foram feitas, porque, que lógica mental usaram para criá-las, porque... e etc...

Outro Exemplo: Aprendendo com idéias aqui do fórum e outras perguntas, e através de uma resposta do Paulo sobre vector de vector em C++, Montei um Database assim. Muito bom, prático, funciona... Mas decidi fazer depois ele na mão, sem essas facilidades todas, e por isso estou estudando ponteiros e malloc pq eu mesmo quero fazer isso em C. É fácil usar string em C++ mas isso não ensina nada! Foi graças a um array de char que entendi o que é de verdade uma string!

Mas mesmo um char possue um monte de código oculto pra ele existir! E que acredito que só devo saber qdo aprender Assembly!

Logo pra mim, economizar Bytes é reduzir a complexidade de um Objeto pra me facilitar o aprendizado! E ao colocar uma Biblioteca em meu programa, significa que estou ignorando enxergar e aprender um monte de coisas ocultas por trás delas!

Eu estou indo na contra-mão da história... Meu objetivo não é programar pra ninguém, meu objetivo e entender como funciona esse básico da programação que começa com Aceso e Apagado, e disso vai para um pequeno microship e depois para uma comunicação escrita! E sei que é um Gigante Longo caminho, começando no C, depois para o Assembly... E deverão ser dezenas de anos aprendendo!

Meu computador com Linux possue 32Gb de RAM, mais que óbvio que nunca foi importante pro meu PC qto de memória meu programinha em C vai usar. Tanto que a pouco fazendo testes com uma struct precisei adicionar a opção -mcmodel=medium para poder compilar visto que a qtd de memória alocada era de fato gigantesca, claro que isso resolveu o problema para a struct ser aceita pelo compilador! Mas não é assim que desejo resolver problemas, quero alocar somente e puramente o que de fato é necessário!

Em C aprendi que cada palavra que escrevo usa 1 Byte!
Olha que LEGAL e Interessante isso! Hoje todas as vezes que escrevo um texto pra guardar, SEI exatamente que gasto 1 Byte por palavra! E gosto de economizar palavras em meus textos, assim sei que não estou disperdiçando ou mesmo quando estou disperdiçando e o porque! E quem me ensinou isso foi C e seu char.

Não sei as outras pessoas, mas me fascina saber esse tipo de coisa! Fiquei muito Feliz qdo pude entender o porque tal arquivo tem tantos bytes e etc... Fiquei feliz de pegar um simples editor de texto, escrever 8 bytes nele, salvar e verificar que tinha mesmo 8 bytes! Achei isso Fascinante!


7. Re: Dúvida Básica sobre bibliotecas .h

berghetti
berghetti

(usa Debian)

Enviado em 10/02/2022 - 18:06h


Funções utilizadas de bibliotecas que são lincadas dinamicamente, como exemplo a libc,
a função em si não fica no seu executável, apenas uma chamada para a função fica.

por exemplo,
ao incluir o header stdio.h e utilizar a função puts,
no seu executável vai ter a chamada apenas para essa função.

Você pode utilizar o programa objdump pra ver oque tem no seu executável.