Undefined function reference

5

I have a problem related to the modularization of my project. Do not get too much into the logic of the program, because the biggest problem I face is the fact that the program does not compile. I think the problem lies in linking between the source and header files but I'm not sure.

The project files are below.

// main.cpp
#include <stdio.h>
#include "geometria.h"
#include "interface.h"


int main(void){

char carac ;
unsigned valor, raio, altura , lado1, lado2;

Apresentacao();

printf("***MENU DE OPCOES***\n");
printf("1-Area de um circulo\n");
printf("2-Volume de um cilindro\n");
printf("3-Volume de um cone\n");
printf("4-Area de um retangulo\n");
printf("5-sair do programa\n");

scanf("%u", &valor);

valor = LeOpcao( 1, 5 );

valor = LeValor();

while( valor != 5 ) {

    printf("\nOvalor lido foi : %u\n", valor);

    carac = (char) valor;

    switch( valor ){

        case '1': printf("Digite o valor do raio: ");
        scanf("%u", &raio);
        printf("\n\nA area do circulo e %u\n", AreaCirculo( raio ) ) ;
        break;

        case '2': printf("Digite o valor do raio: ");
        scanf("%u\n", &raio);
        printf("Digite o valor da altura: ");
        scanf("%u", &altura);
        printf("\n\nO Volume do cilindro e de %u\n", VolumeCilindro( raio ,altura ));
        break;

        case '3': printf("Digite o valor do raio: ");
        scanf("%u", &raio);
        printf("Digite o valor da altura: ");
        scanf("%u", &altura);
        printf("\n\nO Volume do cilindro e de %u\n", VolumeCone( raio ,altura ));
        break;

        default: printf("Didite o valor do primeiro lado: ");
        scanf("%u\n", &lado1);
        printf("Didite o valor do segundo lado: ");
        scanf("%u", &lado2);
        printf("\n\nA area do quadrado e de %u ", AreaRetangulo( lado1 , lado2 ));

    }


}

return 0;

}

.

//geometria.c
#include <stdio.h>
#include "geometria.h"

static unsigned area, volume ;

unsigned AreaCirculo( unsigned raio ){

area = 2*3,14*raio*raio ;

return area;

}

unsigned VolumeCilindro( unsigned  raio , unsigned altura ){

volume = 2*3,14*raio*raio*altura ;

return volume;

}

unsigned VolumeCone( unsigned raio , unsigned altura ){

volume = 2*3,14*raio*raio*altura/3 ;

return volume;

}

unsigned AreaRetangulo( unsigned lado1 , unsigned lado2 ){

area = lado1*lado2 ;

return area;

}

.

//geometria.h

#ifndef GEOMETRIA_H_INCLUDED
#define GEOMETRIA_H_INCLUDED


unsigned AreaCirculo( unsigned raio );

unsigned VolumeCilindro( unsigned  raio , unsigned altura );

unsigned VolumeCone( unsigned raio , unsigned altura );

unsigned AreaRetangulo( unsigned lado1 , unsigned lado2 );


#endif // GEOMETRIA_H_INCLUDED

.

// interface.c
#include <stdio.h>
#include <stdarg.h>
#include "interface.h"

void LimpaBuffer(void){

    int valorLido;

    do{
        valorLido = getchar();
    } while ((valorLido != '\n') && (valorLido != EOF));

}


void ApresentaMenu( int nItens , int menorOpcao , ... ){

    int i;
    va_list argumentos;

    /*inicia lista de argumentos variáveis*/


    va_start ( argumentos , menorOpcao );


    for( i =0 ; i < nItens ; ++i ){

        printf("%c-%s", menorOpcao++ , va_arg(argumentos, char * ) );

    }

    va_end(argumentos);



}


void Apresentacao(void){

    printf("\n\n\n");

    printf("***GEOMETRIA***");

    printf("\n\n\n");

    printf(" Esse programa tem como proposito fazer calculo de uma serie ");
    printf("de opcoes apresentadas abaixo no menu. \n\n");

}


int LeOpcao( int menorValor, int maiorValor ){

    int op;

    while(1){

        if( op >= menorValor && op <= maiorValor ){

            LimpaBuffer();
            break;
        }

        else{

            printf("\nOpcao invalida. Tente Novamente.");
            printf("\nA opcao deve estar entre %c e %c.\n", menorValor,    maiorValor);

            LimpaBuffer();

        }

    }


}

long unsigned LeValor(void){

    long valor;
    unsigned teste;

    teste = scanf("%ld", &valor);

    while( !teste || valor < 0 ){

        if(teste){

            printf("\nO valor %ld nao e valido", valor);

        }

        else{

        printf("\nO valor introduzido nao e valido");

        }

        printf("\nIntroduza um numero maior que zero: ");
        LimpaBuffer();
        teste = scanf("%ld", &valor);

    }

    LimpaBuffer();

    return valor;

}

.

//Interface.h
#ifndef INTERFACE_H_INCLUDED
#define INTERFACE_H_INCLUDED

void LimpaBuffer(void);

void ApresentaMenu( int nItens , int menorOpcao , ... );

void Apresentacao(void);

int LeOpcao( int menorValor, int maiorValor );

long  unsigned LeValor(void);

#endif // INTERFACE_H_INCLUDED

I have tried everything to solve the following problems listed below. All related to functions imported into the main.c file.

$ ls
bin          geometria.cbp     geometria.layout  main.c
geometria    geometria.depend  interface.c       main.cpp
geometria.c  geometria.h       interface.h       obj

$ gcc -o testit main.c
/tmp/cccNrsAz.o: na função 'main':
main.c:(.text+0x18): referência indefinida para 'Apresentacao'
main.c:(.text+0x79): referência indefinida para 'LeOpcao'
main.c:(.text+0x7e): referência indefinida para 'LeValor'
main.c:(.text+0xe9): referência indefinida para 'AreaCirculo'
main.c:(.text+0x158): referência indefinida para 'VolumeCilindro'
main.c:(.text+0x1c7): referência indefinida para 'VolumeCone'
main.c:(.text+0x233): referência indefinida para 'AreaRetangulo'
collect2: error: ld returned 1 exit status

I do not know what the real problem is with linkagen and header . At the moment I am using Code Blocks, but I have tried to create in separate files (outside the IDE project, by gedit) and linka them by the console, but without success.

    
asked by anonymous 09.01.2015 / 02:23

2 answers

6

Try compiling with:

gcc -o testit main.c geometria.c interface.c

The fact that you put #include with headers does not make the codes included as well. So you have to indicate to the compiler all the files that contain codes under penalty of missing their members to produce a valid output.

Since you have listed a code with .cpp extension, if you want to compile in C ++ you should use g++ to compile and not gcc . But that does not seem to be the case. Your code seems to be all C and there is no need to use the C ++ compiler.

An IDE usually calls the compiler with all sources automatically as long as it knows what those files are. The fact that you edit a file on it does not make you aware that this file is needed to compile the application. You need to create a project in the IDE. This project will contain all the information needed to generate the application. It is a hand in the wheel but it does not work miracles. You should give background information that only you know. You should manually add the files in the project or create a new file within the project so the IDE will be aware that they need to be compiled.

Documentation and Wiki of CodeBlocks.

GCC Handbook .

GCC Tutorial .

    
09.01.2015 / 02:31
5

I think you are confusing the concept of "linking": it is not the source and header that are linked, strong> that link to each other to form the executable (or library / dll). The compilation steps are as follows, roughly:

  • Each source file is compiled independently of the other source files;
    • If a file uses a function that is not defined in this same file, the header can be used to say "this function is not here anymore, it will appear in the future." >
  • The result of compiling each source (i.e. the various object files resulting from the compilation, one per source file) are linked together to produce the complete program.
    • At that time, yes, a file is crossed with the others, and it tries to make sure that any function used is actually implemented somewhere.
  • When you call the compiler without specifying a phase, it assumes that all phases must be executed - starting from the sources, until you reach the executable. That is, you need to specify all the source files needed to produce the executable, not just the On the other hand, if you want to compile each source individually, and then use a tool / linking step with the produced object files, use the main option, and do not specify an output file using the -c :

    gcc -c main.c
    

    The result will be a -o file, which can be used in the linking step along with all main.o generated in compiling other sources.

        
    09.01.2015 / 02:49