Departamento de Ciência da Computação - IME - USP

Introdução à Computação

 

 

Perguntas e Respostas mais Frequentes sobre Compilação

 


Para que essas opções de compilação?

Essas duas opções ajudam a tirar vários erros que poderiam passar despercebidos. Sobre as opções de compilação que estamos usando:

-ansi -pedantic

Tentamos uniformizar o uso de um compilador para que fosse possível testar os EPs com uma certa facilidade. O objetivo maior da disciplina é, usando C, mostrar como funcionam as várias linguagens de programação, porém sem precisar ficar falando nisso. Assim como outras linguagens, o C tem um padrão e vários dialetos. É bom escrever um programa em C que possa ser compilado em qualquer máquina com qualquer sistema operacional. Isto é o que as pessoas chamam de portabilidade: a possibilidade de "portar" o programa de um computador para outro usando qualquer compilador decente.

O padrão ANSI serve nesse sentido de portabilidade.

Certamente evita comentários com "//", o que por si só não é grave, mas que indica que as outras opções de compilação não estão sendo usadas. Pode servir também para impedir outras construções esquisitas, mas que não sei se isso seria importante.

Olhando em conjunto, o -ansi -pedantic não é tão importante, uma vez que o compilador que a gente está usando, o tal do gcc, é um compilador muito bem comportado no sentido de não dar acesso fácil a particularidades de instalação.

Sempre que um aluno PRECISAR MUITO usar um comando não dado em aula, dá para perceber que a disciplina não conseguiu ensinar direito alguma coisa para ele. Forçar a usar só comandos dados em aula, bem mais restrito do que usar ANSI C, é bom para ter essa avaliação do processo de aprendizado.

O que significa "warning: ignoring return value of 'scanf' declared with attribute 'warn_unused_result'"?

Resposta curta: não se preocupe com esse alerta. Esse é o único alerta que você pode ignorar.

Resposta um pouco mais completa: a função scanf() devolve o número que objetos lidos com sucesso. Alguns sistemas dão esse alerta se o valor devolvido por scanf() não é usado no programa.

O valor devolvido por scanf() pode ser usado da seguinte forma (o programa abaixo não gera o alerta em questão):

#include <stdio.h>

int main()
{
    int a;
 
    if (scanf("%d", &a) != 1) {
        printf("Falha na leitura de um inteiro\n");
        return 1; /* valor diferente de 0 em caso de término
                     inesperado do programa */
    }
    printf("Valor lido: %d\n", a);

    return 0;  
}

O que significa "warning: control reaches end of non-void function"? (resposta curta)

Uma função (o main?) não é do tipo 'void' e não tem um "return <expressão>" no final.

A compilação do programa a seguir pelo gcc apresenta o aviso:

In function 'main':
10: warning: control reaches end of non-void function
#include <stdio.h>

int main()
{
    int a, b, soma;

    scanf("%d %d", &a, &b);
    soma = a + b;
    printf("%d + %d = %d\n", a, b, soma);

    /* Aqui, no final do programa, falta "return 0;" */
}
Falta "return 0;" no final do programa.

O que significa "warning: too few arguments for format"?

Deve estar faltando uma variável que você quer imprimir num printf ou uma variável a ser lida num scanf.

A compilação do programa a seguir apresenta os avisos:

In function 'main':
7: warning: too few arguments for format
9: warning: too few arguments for format
#include <stdio.h>

int main()
{
    int a, b, soma;

    scanf("%d %d %d", &a, &b);
    soma = a + b;
    printf("%d + %d = %d\n", a, b);

    return 0;
}
Na linha 7 há três '%d' e há apenas duas variáveis para serem inicializadas na leitura: a e b. Na linha 9 há um erro idêntico com o printf.

O que significa "warning: too many arguments for format"?

Deve estar faltando um '%d' ou '%f' ou '%c' num comando printf ou scanf.

A compilação do programa a seguir apresenta os avisos:

In function 'main':
7: warning: too many arguments for format
9: warning: too many arguments for format
#include <stdio.h>

int main()
{
    int a, b, soma;

    scanf("%d", &a, &b);
    soma = a + b;
    printf("%d + %d = \n", a, b, soma);

    return 0;
}
Na linha 7 há apenas um '%d' e há duas variáveis para serem inicializadas na leitura: a e b. Na linha 9 há um erro idêntico com o printf.

O que significa "warning: suggest parentheses around assignment used as truth value"?

O seu programa contém, provavelmente, uma atribuição no lugar de uma comparação.
Possivelmente você digitou um '=' (atribuição) onde deveria ser '==' (comparação).
Também pode ser que você digitou um "=!" onde deveria ser "!=".

A compilação do programa a seguir apresenta o aviso:

In function 'main':
8: warning: suggest parentheses around assignment used as truth value
#include <stdio.h>

int main()
{
    int a, b;

    scanf("%d %d", &a, &b);
    if (a = b) 
    {
        printf("o conteudo das variaveis sao o mesmo.\n");
    }

    return 0;
}
Na linha 8 vemos um 'a = b' onde deveria estar um 'a == b'.

O que significa "error: invalid lvalue in assignment"?

O seu programa contém, provavelmente, uma atribuição no lugar de uma comparação.
Possivelmente você digitou um '=' (atribuição) onde deveria ser '==' (comparação).
Também pode ser que você digitou um "=!" onde deveria ser "!=".

A compilação do programa a seguir apresenta o aviso:

In function 'main':
8: error: invalid lvalue in assignment
#include <stdio.h>

int main()
{
    int a, b;

    scanf("%d %d", &a, &b);
    if (5 > 4 && a = b) 
    {
        printf("o conteudo das variaveis sao o mesmo.\n");
    }

    return 0;
}
Na linha 8 vemos um 'a = b' onde deveria estar um 'a == b'.

O que significa "warning: unused variable 'bla'"?

A variável de nome 'bla' foi declarada, mas não está sendo usada pelo programa.
Se a variável, de fato, é desnecessária, então ela deve ser removida do programa.

A compilação do programa a seguir apresenta o aviso:

In function 'main':
5: warning: unused variable 'soma'
#include <stdio.h>

int main()
{
    int a, b, soma;

    scanf("%d %d", &a, &b);
    printf("%d + %d = %d\n", a, b, a+b);

    return 0;
}
A variável 'soma' foi declarada na linha 5, mas não foi utilizada pelo programa.

O que significa "warning: format '%d' expects type 'int', but argument 'xx' has type 'int *'"?

É possível que em um printf haja um '&' antes de uma váriavel cujo conteúdo se deseja imprimir: printf("%d",&x);.
Remova o '&' do printf.

A compilação do programa a seguir apresenta o aviso:

In function 'main':
9: warning: format '%d' expects type 'int', but argument 4 has type 'int *'
#include <stdio.h>

int main()
{
    int a, b, soma;

    scanf("%d %d", &a, &b);
    soma = a + b;
    printf("%d + %d = %d\n", a, b, &soma);

    return 0;
}
Na linha 9 há um '&' antes da variável 'soma'.

O que significa "warning: spurious trailing '%' in format"?

No programa deve ter algum scanf ou printf com um '%' onde deveria estar um '%d' ou algum outro formato.

A compilação do programa a seguir apresenta os avisos:

In function 'main':
7: warning: spurious trailing '%' in format
7: warning: too many arguments for format
#include <stdio.h>

int main()
{
    int a, b, soma;

    scanf("%d %", &a, &b);
    soma = a + b;
    printf("%d + %d = %d\n", a, b, soma);

    return 0;
}
Na linha 7 há um '%' onde deveria estar um '%d'. O outro aviso (too many arguments for format) também é consequência desse mesmo erro.

O que significa "warning: ISO C90 forbids mixed declarations and code"?

O seu programa tem declaração de variáveis misturada com comandos.
É recomendado que todas as variáveis sejam declaradas no início da função (main).

A compilação do programa a seguir apresenta o aviso:

In function 'main':
9: warning: ISO C90 forbids mixed declarations and code
#include <stdio.h>

int main()
{
    int a, b;

    scanf("%d %d", &a, &b);

    int soma;
    soma = a + b;
    printf("%d + %d = %d\n", a, b, soma);

    return 0;
}
Na linha 9 está declarada a variável 'soma', depois do comando de leitura (scanf). No caso, a variável 'soma' deveria ter sido declarada no início do main, junto com as outras variáveis.

A compilação do programa a seguir apresenta os seguintes avisos:

In function 'main':
9: warning: ISO C90 forbids mixed declarations and code
#include <stdio.h>

int main()
{
    int i, j,  nI;

    scanf("%d", &nI);

    int ilha[100][100];

    for (i = 0; i < nI; i++)
      for (j = 0; j < nI; j++)
        ilha[i][j] = 0;

    return 0;
}
Na linha 9 do 'main' foi declarada a matriz ilha entre os comandos scanf e for. A declaração de variáveis deve ser feita no início das funções.

O que significa "warning: implicit declaration of function 'bla'"?

A função 'bla' está sendo usada no seu programa sem ter sido definida.
É possível que tenha ocorrido apenas um erro de digitação, como digitar print em vez de printf.

A compilação do programa a seguir apresenta o aviso e erro:

In function 'main':
9: warning: implicit declaration of function 'print'
/tmp/ccC14gmU.o: In function 'main':
(.text+0x48): undefined reference to 'print'
collect2: ld returned 1 exit status
#include <stdio.h>

int main()
{
    int a, b, soma;

    scanf("%d %d", &a, &b);
    soma = a + b;
    print("%d + %d = %d\n", a, b, soma);

    return 0;
}
Na linha 9 está escrito 'print' em vez de 'printf'. As outras mensagens de erro são consequência desse mesmo erro tipográfico.

O que significa "warning: implicit declaration of function 'scanf' ('printf')"?

É possível que no início do programa esteja faltando o 'include <stdio.h>':
#include <stdio.h>

A compilação do programa a seguir apresenta os avisos:

In function 'main':
5: warning: implicit declaration of function 'scanf'
5: warning: incompatible implicit declaration of built-in function 'scanf'
7: warning: implicit declaration of function 'printf'
7: warning: incompatible implicit declaration of built-in function 'printf'
int main()
{
    int a, b, soma;

    scanf("%d %d", &a, &b);
    soma = a + b;
    printf("%d + %d = %d\n", a, b, soma);

    return 0;
}
Na linha 5 aparece o 'scanf' e na linha 7 o 'printf'. Os warnings foram gerados pela falta do 'include'.

O que significa "error: expected expression before '/' token"?

É possível que no programa haja algum '//'.
Em C padrão ANSI comentários devem estar entre '/* <comentário> */':
/* Este e um comentario em C padrao ANSI */

A compilação do programa a seguir apresenta os erros:

In function 'main':
5: error: expected expression before '/' token
12: error: expected expression before '/' token
#include <stdio.h>

int main()
{
    int a, b, soma; // declaracao de variaveis

    /* Este e'um comentario em C padrao ANSI. */
    scanf("%d %d", &a, &b);
    soma = a + b;
    printf("%d + %d = %d\n", a, b, soma);

    return 0;  // termino do  programa 
}
Nas linhas 5 e 12 está sendo usado '//' em vez de '/* <comentário> */'.

O que significa "warning: unknown escape sequence"?

É possível que o programa tenha um 'printf' com um '\' em vez de um '\n'.

A compilação do programa a seguir apresenta o aviso:

9:10: warning: unknown escape sequence: '\040'
#include <stdio.h>

int main()
{
    int a, b, soma;
 
    scanf("%d %d", &a, &b);
    soma = a + b;
    printf("%d + %d = %d\ ", a, b, soma);   /* ERRO */ 

    return 0;  
}

Na linha 9 há um '\' no lugar de um '\n'.

O que significa "warning: 'bla' is used uninitialized in this function"?

Significa que a variável bla do seu programa está sendo usada sem ter sido inicializada. Esta mensagem, tipicamente, indica um erro de lógica.

A compilação do programa a seguir apresenta o aviso:

In function 'main':
8: warning: 'a' is used uninitialized in this function
#include <stdio.h>

int main()
{
    int a, b, soma;

    b = 2;
    soma = a + b;  /* ERRO */ 
    printf("%d + %d = %d\n", a, b, soma);

    return 0;
}
De fato, a variável a foi usada na linha 8, em 'soma = a + b' sem ter sido inicializada. Para que o aviso desapareça, basta inicializar a variável a. Com qual valor inicializar? Com 0? com -134? A resposta é: depende! No exemplo, depende de qual a soma que se deseja fazer no programa. A soma é 0+2? A soma é -134+2?

O que significa "warning: 'bla' may be used uninitialized in this function"?

Significa que é possível que a variável bla do seu programa esteja sendo usada sem ter sido inicializada. Esta mensagem, tipicamente, indica um erro de lógica ou uma estrutura "rebuscada" do seu programa.

A compilação do programa a seguir apresenta o aviso:

In function 'main':
5: warning: 'b'  may be used uninitialized in this function
#include <stdio.h>

int main()
{
    int a, b;

    printf("Digite 1 ou 2: ");
    scanf("%d", &a);

    if (a == 1)
    {
        b = 2;
    }
    if (a == 2)
    {
        b = 1;
    }

    b = b + 1; 
    printf("b = %d\n", b);

    return 0;
}
O número indicado pelo aviso é o número da linha em que a variável b foi declarada. Para o programador pode ser evidente que a variável b sempre será inicializada, já que ele pede que seja digitado 1 ou 2 na leitura do valor de a. No entanto, para o compilador, que não está a par da lógica do programa, não é evidente que o valor atribuido inicialmente à variável a pela leitura seja 1 ou 2. Por isto, levando em consideração o comando "b = b + 1" o compilador avisa que a variável b pode (may be) estar sendo usada sem ter sido inicializada.

O programa a seguir é menos "rebuscado" e tem o mesmo efeito do programa anterior. Para este, programa o compilador não apresenta aviso algum

#include <stdio.h>

int main()
{
    int a, b;

    printf("Digite 1 ou 2: ");
    scanf("%d", &a);

    if (a == 1)
    {
        b = 2;
    }
    else
    {
        b = 1;
    }

    b = b + 1;
    printf("b = %d\n", b);

    return 0;
}

O que significa "warning: passing arg 'xx' of 'bla' makes pointer from integer without a cast"?

Significa que a função 'bla', na sua declaração, tem como primeiro parâmetro uma variável com '*' e na chamada da função esta faltando um '&' antes do correspondente primeiro argumento (arg 1).

A compilação do programa a seguir apresenta o aviso:

In function 'main':
15: warning: passing argument 1 of 'soma' makes pointer from integer without a cast
#include <stdio.h>

/* prototipo da funcao soma */
void soma(int *k);

/* main */
int main()
{
    int i;

    i = 0;
    while (i < 10)
    {
        printf("i = %d\n", i);
        soma(i);   /* ERRO */ 
    }

    return 0;
}

/* declaracao da funcao da soma */
void soma(int *k)
{
    *k = *k + 1;
}
Na linha 15, na função 'main', está faltando um '&' antes da variável 'i', deveria estar escrito 'soma(&i)' em vez de simplesmente 'soma(i)'.

O que significa "warning: assignment makes integer from pointer without a cast"?

Significa que o seu programa esta usando uma variável que foi declarada com '*' sem a '*'.

A compilação do programa a seguir apresenta o aviso:

In function 'soma':
24: warning: assignment makes integer from pointer without a cast
#include <stdio.h>

/* prototipo da funcao soma */
void soma(int *k);

/* main */
int main()
{
    int i;

    i = 0;
    while (i < 10)
    {
        printf("i = %d\n", i);
        soma(&i);
    }

    return 0;
}

/* declaracao da funcao soma */
void soma(int *k)
{
    *k = k + 1;   /* ERRO */ 
}
Na linha 24, na função soma, está faltando um '*' antes da variável 'k'; deveria estar escrito '*k = *k + 1;' em vez de '*k = k + 1;'.

O que significa "warning: passing arg 'xx' of 'bla' from incompatible pointer type"?

Significa que o seu programa esta chamando a função 'bla' passando como primeiro argumento (arg 1) uma váriavel de tipo diferente daquele declarado.

A compilação do programa a seguir apresenta o aviso:

In function 'main':
15: warning: passing argument 1 of 'soma' from incompatible pointer type
#include <stdio.h>

/* prototipo da funcao soma */
void soma(int *k);

/* main */
int main()
{
    float x;

    x = 0;
    while (x < 10)
    {
        printf("x = %f\n", x);
        soma(&x);    /* ERRO */
    }

    return 0;
}

/* declaracao da funcao soma */
void soma(int *k)
{
    *k = *k + 1;
}
Na linha 15, na função 'main', a variável passada para a função 'soma' é do tipo float, mas o correspondente parâmetro *k na declaração da função é do tipo "int".

O que significa "error: invalid operands to binary *"?

É possivel que no seu programa uma variável tenha sido declarada com '*' e esteja faltando um '*' quando ela está sendo usada em alguma operação aritmética.

A compilação do programa a seguir apresenta o erro:

In function 'multiplica':
24: error: invalid operands to binary *
#include <stdio.h>

/* prototipo da funcao multiplica */
void multiplica(int *k);

/* main */
int main()
{
    int i;

    i = 0;
    while (i < 10)
    {
        printf("i = %d\n", i);
        multiplica(&i);
    }

    return 0;
}

/* declaracao da funcao multiplica */
void multiplica(int *k)
{
  *k = k * 2;    /* ERRO */
}
Na linha 24, na função multiplica, está faltando um '*' antes da variável 'k'; deveria estar escrito '*k = *k * 2;' em vez de '*k = k * 2;'.

O que significa "warning: control reaches end at non-void function"? (resposta longa)

Resposta mais longa. O compilador está avisando que há uma função que é do tipo int ou float que não tem return ou não está claro para o compilador se a execução da função sempre chega a um return. Não há problemas em deixar return's dentro de if-else, desde que o programador tenha certeza que sempre a função termina num desses return's. Com esse tipo de warning, o compilador está dando alguma dica de que a função está um pouco desorganizada, mas tudo bem.

A compilação do programa a seguir não dá esse warning.

#include <stdio.h>

int main()
{
    int a;

    a = 12;

    if (a > 0)
      return 0;
    else
      return 1;

}
Já a compilação do programa abaixo apresenta esse warning:
#include <stdio.h>

int main()
{
    int a;

    a = 12;

    if (a > 0)
      return 0;

    if (a <= 0)
      return 1;
}
Pode-se perceber que o segundo main é mais confuso que o primeiro.

O que significa "warning: type defaults to 'int' in declaration of 'bla'"?

Esse aviso diz que não foi especificado o tipo da função 'bla' do seu programa e, portanto, está sendo assumido que a função é do tipo 'int' (isto é, a função devolve um valor que é um número inteiro). A declaração de uma função deve seguir o formato:
<tipo da função> <nome da função>(<lista de parâmetros>)
{
  <variáveis locais>

  <lista de comandos>
}
<tipo da função> pode ser, por exemplo, int, float, char ou ainda void.

A compilação do programa a seguir apresenta os seguintes avisos:

4: warning: data definition has no type or storage class
4: warning: type defaults to 'int' in declaration of 'f'
24: warning: return type defaults to 'int'
#include <stdio.h>

/* prototipo */
f(float a, float b, int k);  /* Falta o tipo da funcao */

/* main */
int main()
{
    int   i;
    float x;

    i = 0;
    while (i < 10)
    {
        x = f(0,1,i);
        printf("x = %f\n", x);
    }

    return 0;
}

/* funcao f */
f(float a, float b, int k)
{
    float deltax;

    deltax = (b - a)/k;

    return deltax;
}
Nas linhas 4 e 24 não foi especificado o tipo da função 'f' que, portanto, é suposto como sendo do tipo 'int'.

O que significa "error: expected identifier or '(' before '{' token"?

É possível que, na declaração de uma função, haja um ';' entre o protótipo e o corpo da função.

A compilação do programa a seguir apresenta o seguinte erro:

24: error: expected identifier or '(' before '{' token
#include <stdio.h>

/* prototipo */
float f(float a, float b, int k); 

/* main */
int main()
{
    int   i;
    float x;

    i = 0;
    while (i < 10)
    {
        x = f(0,1,i);
        printf("x = %f\n", x);
    }

    return 0;
}

/* funcao f */
float f(float a, float b, int k); /* ERRO: este ';' esta sobrando */
{
    float deltax;

    deltax = (b - a)/k;
  
    return deltax;
}
Na linha 23 há um ';' entre o protótipo e o corpo da função. Removendo-se esse ';' o programa compila sem erros ou avisos.

O que significa "error: 'bla' redeclared as different kind of symbol"?

Significa que, em alguma função, 'bla' é o nome de um parâmetro e de uma variável local.

A compilação do programa a seguir apresenta os seguintes erros:

In function 'f':
26: error: 'k' redeclared as different kind of symbol
23: error: previous definition of 'k' was here
#include <stdio.h>

/* prototipo */
float f(float a, float b, int k); 

/* main */
int main()
{
    int   i;
    float x;

    i = 0;
    while (i < 10)
    {
        x = f(0,1,i);
        printf("x = %f\n", x);
    }

    return 0;
}

/* funcao f */
float f(float a, float b, int k)
{
    float deltax;
    int k;  /* k ja foi declarado como parametro */

    k = k*10;
    deltax = (b - a)/k;
  
    return deltax;
}
Na linha 26 da função 'f', a variável local de nome k foi declarada, mas já havia um parâmetro com este nome na linha 23 ('int k').

A compilação do programa a seguir apresenta os seguintes erros:

In function 'f':
26: error: 'k' redeclared as different kind of symbol
23: error: previous definition of 'k' was here
#include <stdio.h>

/* prototipo */
float f(float a, float b, int *k); 

/* main */
int main()
{
    int   i;
    float x;

    i = 0;
    while (i < 10)
    {
        x = f(0,1,&i);
        printf("x = %f\n", x);
    }

    return 0;
}

/* funcao f */
float f(float a, float b, int *k)
{
    float deltax;
    int k;  /* k ja foi declarado como parametro */

    k = k*10;
    deltax = (b - a)/k;
  
    return deltax;
}
Na linha 26 da função 'f' a variável local de nome k foi declarada, mas já havia uma parâmetro com este nome na linha 23 ('int *k').

O que significa "warning: ISO C90 forbids variable-size array 'bla'"?

Isto significa que no seu programa uma matriz está sendo declarada com uma váriavel como dimensão em vez de uma constante (número inteiro).

A compilação do programa a seguir apresenta os seguintes avisos:

In function 'main':
6: warning: ISO C90 forbids variable-size array 'ilha'
6: warning: ISO C90 forbids variable-size array 'ilha'
#include <stdio.h>

int main()
{
    int i, j,  nI;
    int ilha[nI][nI]; /* deveria ser um numero em vez de uma variável */

    scanf("%d", &nI);

    for (i = 0; i < nI; i++)
      for (j = 0; j < nI; j++)
        ilha[i][j] = 0;

    return 0;
}
Na linha 6 do 'main' foi usada a variável nI para indicar a dimensão da matriz ilha. Em vez de uma váriavel como nI, a declaração deve usar um número, por exemplo "int ilha[100][100];".

O que significa "warning: no newline at end of file"?

Para eliminar esse aviso, acrescente uma linha em branco no final do arquivo que contém o seu programa.

É importante que programas não apresentem avisos durante a compilação, já que, frequentemente, avisos na verdade indicam erros de lógica. No entanto, este aviso em particular, pode ser ignorado...

Segundo uma mensagem no mailing list for the GCC project, o padrão da linguagem C recomenda que um arquivo com um programa termine com o caractere "new-line", que não deve ser imediatamente precedido de backslash ('\'). Como isto é uma recomendação, os desenvolvedores do compilador fazem com que uma mensagem de violação dessa recomendação seja emitida.

O que significa "error: void value not ignored as it ought to be"?

Você está tentando usar o valor devolvido por uma função do tipo void. Porém funções do tipo void não devolvem nada. Exemplo:
/* Colaboração de Henrique dos Reis Cadioli */
#include <stdio.h>

void f(int a)
{
    a = a + 1;
}

int main () 
{
    int a,b;

    b = 5;
    a = f(b);

    printf("a = %d\n", a);

    return 0;
}

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.