0

The structure of my codes is like:

passivertm_formal.c:

#include "CPML_profile.c"
int main(int argc, char* argv[])
{
    int n1,n2;
    float *p1,*p2;
    n1=1;
    n2=2;
    p1=(float*)calloc(n1,sizeof(float));
    p2=(float*)calloc(n2,sizeof(float));
    CPML_profile(p1,p2);
    ...
}

CPML_profile.c:

#include <stdio.h>
#include <math.h>
void CPML_profile(float *p1, float *p2)
{
  extern int n1,n2;
  ...
}

But when I compile the two codes, error shows:

CPML_profile.o: In function `CPML_profile':
CPML_profile.c:(.text+0x0): multiple definition of `CPML_profile'
passivertm_formal.o:passivertm_formal.c:(.text+0x0): first defined here
passivertm_formal.o: In function `CPML_profile':
passivertm_formal.c:(.text+0x13): undefined reference to `n1'
passivertm_formal.c:(.text+0x1b): undefined reference to `n2'
CPML_profile.o: In function `CPML_profile':
CPML_profile.c:(.text+0x13): undefined reference to `n1'
CPML_profile.c:(.text+0x1b): undefined reference to `n2'

Can anybody figure out why it happens?

cleblanc
  • 3,678
  • 1
  • 13
  • 16
Tom
  • 3
  • 2
  • 5
  • 2
    Don't include `.c` files, or if you do, do it only once and don't compile it independently. – Mat Jun 27 '18 at 13:13
  • And `n1` and `n2` are local to main, you can't access them from anywhere else. Pass them as parameters. – Mat Jun 27 '18 at 13:14
  • `p1=(float*)calloc(n1,sizeof(float)); p1=(float*)calloc(n2,sizeof(float));` copy paste typo: you're not allocating `p2` at all. – Jean-François Fabre Jun 27 '18 at 13:19
  • @Mat So you mean if I keep `include "CPML_profile.c"` in code 1, I should only compile `passivertm_formal.c` in my `Makefile`? – Tom Jun 27 '18 at 13:29

1 Answers1

0

First, don't include the .c file, just create a .h file with the function prototype:

#include "CPML_profile.h"

the .h contains:

#pragma once
void CPML_profile(<... function parameters ...>);

Now, n1 and n2 aren't global variables. They're local variables from the main procedure (which is no different from another procedure besides the fact that this is your program entrypoint), you cannot access them from another procedure or file.

Move the declaration of n1 and n2 to the global scope (but I wouldn't recommend that solution)

int n1,n2;

int main(int argc, char* argv[])
{

in your case, why not passing them as parameters, since you're already passing the array of floats:

p1=calloc(n1,sizeof(float));
p2=calloc(n2,sizeof(float));  # BTW: another issue: you're not allocating p2 but p1 twice: ouch!!
CPML_profile(p1,p2,n1,n2);

now:

void CPML_profile(float *p1, float *p2, int n1, int n2)
{

This solution is way cleaner, and allows to use the function in a multithreaded environment/without needing global symbols for n1 and n2

Misc advice: compiling with warnings on would probably have revealed that you were using p2 uninitialized.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • Thank you. I correct my code as your suggestions. But still have an error: `CPML_profile.o: In function `CPML_profile': CPML_profile.c:(.text+0x0): multiple definition of `CPML_profile' passivertm_formal.o:passivertm_formal.c:(.text+0x0): first defined here collect2: error: ld returned 1 exit status make: *** [passivertm] Error 1`. Is it the "include" problem? – Tom Jun 27 '18 at 13:24
  • aah see my edit. Don't include the .c file, but a header file. – Jean-François Fabre Jun 27 '18 at 13:31
  • https://stackoverflow.com/questions/232693/including-one-c-source-file-in-another – ImmortaleVBR Jun 27 '18 at 13:33