Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boas pessoal!!
Outro dia, dando uma olhada no fórum, notei a quantidade de gente que não sabe utilizar um compilador da forma correta. Todo mundo comete erros de sintaxe, esquecemos de colocar ';' no final das instruções, confundimos tipos passados para funções....
Mas o compilador não perdoa, e nos diz tudo que está errado no nosso código, em questão de sintaxe.
Então decidi tentar ensinar a usar um compilador e um debugger, de uma forma básica.
Quem está no linux, muito provavelmente ja tem as duas ferramentas que utilizarei...
minhas versões:
gcc - 4.2.4
gdb - 6.8
Vamos começar com o compilador...
Eu espero que vocês saibam como compilar um código "na mão", isto é, sem "ctrl+f9" do seu IDE.
Para aqueles qu não sabem, a sintaxe do gcc é:
gcc [opções][arquivos][-o saída (opcional)]
Algumas das opções mais utilizadas:
-Idir --> adiciona um diretório "dir" onde o compilador procurará por #includes
-Ldir --> adiciona um diretório "dir" onde o linker procurará por bibliotecas
-larquivo --> Adiciona um bilioteca a linkagem (.a, .lib, .so, .dll...),
se não for uma biblioteca "padrão", deve-se indicar o diretório onde ela se encontra, com -L
Não é preciso escrever o "lib" nem a extensão do arquivo, suponha que você quer incluir a bilbioteca /home/eu/projetos/libteste.so
O seu comando ficaria: gcc -L/home/eu/projetos -lteste
-c --> apenas compila os objetos, não efetua a linkagem
-g --> compila os objetos em debug mode, adicionando informações que permitem a
utilização de um debugger.
-Wopção --> SUA OPÇÃO PREFERIDA!!!, habilita os warnings (avisos) do
compilador, são eles que te avisam onde estão os erros do seu código, te dizem até a
linha... que moleza!
Acho que para já está bom.
Compilando um código
código: http://codepad.org/eOqb8tH6
O que o compilador me disse:
>
victor@matrix:~/Desktop/tuto$ gcc -Wall -Wextra -g code.c
code.c:13: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’
code.c:14: error: expected ‘)’ before ‘*’ token
code.c:15: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
code.c:16: error: expected ‘)’ before ‘*’ token
code.c:17: error: expected ‘)’ before ‘*’ token
code.c: In function ‘main’:
code.c:22: error: ‘node’ undeclared (first use in this function)
code.c:22: error: (Each undeclared identifier is reported only once
code.c:22: error: for each function it appears in.)
code.c:22: error: ‘list’ undeclared (first use in this function)
code.c:24: warning: implicit declaration of function ‘add_node’
code.c:31: error: expected ‘;’ before ‘add_node’
code.c:34: warning: implicit declaration of function ‘print_list’
code.c:38: warning: implicit declaration of function ‘remove_node’
code.c:38: warning: implicit declaration of function ‘find_node’
code.c:45: warning: implicit declaration of function ‘destroy_list’
code.c: At top level:
code.c:53: error: expected ‘)’ before ‘*’ token
code.c:75: error: expected ‘)’ before ‘*’ token
code.c:105: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
code.c:122: error: expected ‘)’ before ‘*’ token
code.c:135: error: expected ‘)’ before ‘*’ token
Notem nas opções que utilizei para compilar o código:
-Wall: dizendo o compilador para mostrar TODOS os warnings
-Wextra: pedindo ainda os warnings extra
-g: debug mode.
E notem que o compilador me falou TUDO que estava errado no código...
A nomenclatura é muito simples:
<nome_do_arquivo>:<número_da_linha>:<error ou warning>: o que você fez de errado
Depois de seguir as mensagens dele, temos outro código:
Ao compilar esse novo código.... tcharaaaam! nenhum erro, nem warning! maravilha!!
Mas e ao executar o programa?
>
victor@matrix:~/Desktop/tuto$ ./a.out
[804a008] 1
[804a018] 2
[804a028] 3
[804a038] 4
[804a048] 5
[804a058] 6
[804a068] 7
[804a078] 8
[804a088] 9
Vamos agora apagar alguns nós (7 e 8)...
[804a008] 1
[804a018] 2
[804a028] 3
[804a038] 4
[804a048] 5
[804a058] 6
[804a088] 9
Vamos liberar a lista inteira...
Segmentation fault
OooOOooOOoops... SIGSEGV...
É Agora que entra o nosso amigo gdb
Entre amanhã e depois escrevo qualquer coisinha sobre como debugar algo no modo texto!
Abraços, até a próxima!!
ps.: Espero que a quantidade de tópicos inúteis diminua, e apareçam mais tópicos interessantes e que tem algo a acrescentar para todo o fórum. http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif
Só complementando o post do Vitor.
-o : Permite que você mude o nome do arquivo de saída, não somente o nome do arquivo executável.
@file : Lê as opções pasadas p/ o compilador a partir de um arquivo texto, sendo que as opções devem ser separadas por espaço.
-std= : Permite escolher o padrão p/ compilar a linguagem.
-fmessage-length=n : Permite modificar o tamanho máximo das mensagens exibidas pelo compilador.
-fsyntax-only : Apenas verifica se o código não possui erros de sintaxe.
-Wfatal-errors : O processo de compilação é interrompido no primeiro erro encontrado, não processando o restante do fonte.
-Wconversion : Avisa sobre conversões implícitas que podem alterar um valor. Exemplo de código:
#include <stdlib.h>
int main (int argc, char *argv[])
{
-Wshadow : Avisa se variáveis locais 'sobrescrevem' declarações globais. Exemplo de código:
#include <stdio.h>
int b = 4;
int main (int argc, char *argv[])
{
-Wuninitialized : Para utilizar esta opção é necessário passar a opção -O. As opções -Wall e -Wextra habilitam uninitialized.
-fstack-protector, -fstack-protector-all e -Wstack-protector: Ao invés de se ter uma mensagem de falha de segmentação, temos um backtrace.
O fstack-protector adiciona código p/ verificar estouro de buffer para as funções que chamam alloca ou que possuam buffers maiores que 8 bytes.
#include <stdio.h>
int main (int argc, char *argv[])
{
std-exemplo.c:4: warning: not protecting function: no buffer at least 8 bytes long
/tmp/ccqFAa6W.o: In function `main':
std-exemplo.c:(.text+0x18): warning: the `gets' function is dangerous and should not be used.
Trocando o tamanho do array para 8:
std-exemplo.c:(.text+0x29): warning: the `gets' function is dangerous and should not be used.
A saída da execução do programa com essas opções é:
stack smashing detected : ./a.out terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x48)[0xb803ddb8]
/lib/libc.so.6(__fortify_fail+0x0)[0xb803dd70]
./a.out[0x80484b7]
/lib/libc.so.6(__libc_start_main+0xe5)[0xb7f6d705]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:12 137968 /home/isis/Imasters/a.out
08049000-0804a000 r--p 00000000 08:12 137968 /home/isis/Imasters/a.out
0804a000-0804b000 rw-p 00001000 08:12 137968 /home/isis/Imasters/a.out
0804b000-0806c000 rw-p 0804b000 00:00 0 [heap]
b7f56000-b7f57000 rw-p b7f56000 00:00 0
b7f57000-b80ac000 r-xp 00000000 08:12 1338 /lib/libc-2.9.so
b80ac000-b80ad000 ---p 00155000 08:12 1338 /lib/libc-2.9.so
b80ad000-b80af000 r--p 00155000 08:12 1338 /lib/libc-2.9.so
b80af000-b80b0000 rw-p 00157000 08:12 1338 /lib/libc-2.9.so
b80b0000-b80b4000 rw-p b80b0000 00:00 0
b80b4000-b80c1000 r-xp 00000000 08:12 91475 /lib/libgcc_s.so.1
b80c1000-b80c2000 r--p 0000c000 08:12 91475 /lib/libgcc_s.so.1
b80c2000-b80c3000 rw-p 0000d000 08:12 91475 /lib/libgcc_s.so.1
b80c3000-b80c4000 rw-p b80c3000 00:00 0
b80c4000-b80e2000 r-xp 00000000 08:12 483 /lib/ld-2.9.so
b80e2000-b80e3000 r--p 0001d000 08:12 483 /lib/ld-2.9.so
b80e3000-b80e4000 rw-p 0001e000 08:12 483 /lib/ld-2.9.so
bfbce000-bfbe3000 rw-p bffeb000 00:00 0 [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]
Abortado
A opção fstack-protect-all não possui limite de bytes.
-glevel : As opções -g e -ggdb para o GDB não torna disponível informações sobre defines. Para ser possível dar um print ou display em defines deve ser especificada a opção -g3.
-pg : Cria código extra p/ que se possa usar o GNU profiler.
-fprofile-arcs : Podemos utilizar esta opção em conjunto com o comando gcov p/ verificar quantas vezes cada linha do programa foi executada.Exemplo:
#include <stdio.h>
float fibrec(float a) {
int main (int argc, char *argv[])
{
std-exemplo.gcda:cannot open data file, assuming not executed
File 'std-exemplo.c'
Lines executed:0.00% of 7
std-exemplo.c:creating 'std-exemplo.c.gcov'
isis@linux-gy11:~/Imasters> cat std-exemplo.c.gcov
-: 0:Source:std-exemplo.c
-: 0:Graph:std-exemplo.gcno
-: 0:Data:-
-: 0:Runs:0
-: 0:Programs:0
-: 1:#include <stdio.h>
#####: 2:float fibrec(float a) {
As linhas que estão com '#' não foram executadas, já que não executamos o programa. Após executar o programa, temos
Lines executed:100.00% of 7
std-exemplo.c:creating 'std-exemplo.c.gcov'
isis@linux-gy11:~/Imasters> cat std-exemplo.c.gcov
-: 0:Source:std-exemplo.c
-: 0:Graph:std-exemplo.gcno
-: 0:Data:std-exemplo.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include <stdio.h>
21891: 2:float fibrec(float a) {