Indefinite reference of functions

Asked

Viewed 15,519 times

5

I have a problem related to modularization of my project. Do not pay too much attention to 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 the linkage among the archives source and header 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 resolve the following problems listed below. All related to functions imported to the main file. c.

$ 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 don’t know what the real problem is that linkage archival source and header. I’m currently using Code Blocks, but I’ve tried creating in separate files (outside the IDE project, by gedit) and linka-them by the console, but without success.

  • 1

    The real problem is that everyone’s first program is something simple, just the main(), in a file. There you add things little by little and see what happens. That’s how you learn. That’s how you learn to find mistakes that are more important than writing code. Then even if you can’t find the problem it becomes easier to ask somewhere what the problem is that is most contained and you don’t need to put long codes that don’t matter much to the problem.

  • 1

    You showed several files, minus the main.c - which is where the problem is occurring! Are sure that’s the same file you want to compile, and not the main.cpp?

  • Take a look at [tour]. You can accept an answer if it solved your problem. You can vote on every post on the site as well. Did any help you more? You need something to be improved?

2 answers

8

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 to be included as well. Then you have to indicate to the compiler all the files containing codes under penalty of missing its members to produce a valid output.

Since you have listed a code with extension .cpp, if you want to compile in C++ you should use g++ to compile and not the gcc. But it 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 fonts automatically as long as it knows what those files are. The fact that you edit a file in it does not make you aware that this file is necessary 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 on the wheel but it does not work miracles. You must give fundamental information that only you know. You should manually add the files to the project or create a new file within the project so the IDE is aware that they need to be compiled.

Documentation and Wiki codeblocks.

Manual of the GCC.

Tutorial GCC.

  • Good. This command did not show any errors on the console. But I don’t know how I do to get around this problem using code Blocks, which presents the same debugging error.

  • So the problem has been solved, now you have a problem with the IDE. It is already another issue and you would have to detail these specific situations. You need to create a project. Theoretically, the IDE would take care of the build if the project was created correctly. Have you read the entire manual? http://www.codeblocks.org/docs/main_codeblocks_en.html Wiki: http://wiki.codeblocks.org/index.php?title=Creating_a_new_project

  • Indeed, the problem persists through the IDE. But I managed to run the program (which I now saw is wrong) compiling and connecting the files by the same console. I’ll have to learn more about how the IDE works, as it is but I practice using them to find errors in the program (logic errors but not debugging errors).

  • @Alexandresantiagodasilva I don’t know Codeblocks, but as you said in the question that created the files "outside the IDE project, by gedit", maybe Codeblocks doesn’t even know that they exist... Him could inspect the contents of the folder by any source file, but most likely it is simply using a Makefile or similar - and if the file created outside the project did not enter the Makefile, it is not considered in the compilation.

  • @Alexandresantiagodasilva the code is full of problems, but you asked not to say anything. There are some very silly mistakes, which is normal for those who are starting out, until conceptual mistakes. I don’t know where you’re learning from and if you’re guessing things on your own but it seems like you’re using what you have no idea what it’s for. Learn all you have to learn about a resource before using it. IDE doesn’t do miracles. It helps you find problems you understand.

  • Really, Disregard the mistakes made. In fact I still have little experience, practice , and theoretical knowledge about programming. I believe that the biggest contribution to the errors is due to the code of the interface file. c, in which I possessed codes that were copied from my books without even understanding them properly.

Show 1 more comment

5

I think you’re confusing the concept of "linkage": it’s not the source and the header that are linked, and yes multiple files object link to each other to form the executable (or library/dll). The compilation steps are the following, roughly speaking:

  1. Each source file is compiled independently of the other source files;
    • If a file uses a function that is not defined in that same file, the header can be used to say "this function is not here anymore exists, in the future it will appear".
  2. The result of the compilation of each source (i.e. the various object files resulting from the compilation, one per source file) are linked together ("linked") to produce the complete programme.
    • At that moment yes, a file is crossed with others, and it is sought to ensure that every function used is actually implemented somewhere.

When calling the compiler without specifying a phase, it assumes that all phases must be executed - starting from the sources, until it reaches the executable. That is, it is necessary to specify all source files needed for executable production, not only what contains the function main.

On the other hand, if you want to compile each font individually, and then use a link tool/step with the produced object files, use the option -c, and do not specify an output file using the function -o:

gcc -c main.c

The result will be a file main.o, which can be used in the link step along with all files .o generated in the compilation of other sources.

  • It really was a gaffe. I thought I could apply this same link concept to both cases (both for source and header files and for merging object files into an executable). I even thought about editing the question but I’ll leave it like this. Well, I’ll stop here so I don’t talk more nonsense kkk.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.