0

i am using makefiles in c, i have three files and each of the three have all the declarations of each variable. so it looks like this when i compile.

/usr/bin/ld: comp_disc.o:(.bss+0x8): multiple definition of `Cost_of_purchase'; main.o:(.bss+0x8): first defined here
/usr/bin/ld: comp_disc.o:(.bss+0x10): multiple definition of `DiscTot'; main.o:(.bss+0x10): first defined here
/usr/bin/ld: comp_disc.o:(.bss+0x18): multiple definition of `Sales_tax'; main.o:(.bss+0x18): first defined here
/usr/bin/ld: comp_disc.o:(.bss+0x20): multiple definition of `Total_price'; main.o:(.bss+0x20): first defined here
/usr/bin/ld: comp_disc.o:(.bss+0x28): multiple definition of `military'; main.o:(.bss+0x28): first defined here

but when i only keep those declarations on main.c i get this.

comp_disc.c:10:12: error: ‘Cost_of_purchase’ undeclared (first use in this function)
   10 |         if(Cost_of_purchase > 150) {
      |            ^~~~~~~~~~~~~~~~
comp_disc.c:11:13: error: ‘Mdisc’ undeclared (first use in this function)
   11 |             Mdisc = .15 * Cost_of_purchase;

so I'm wondering what i need to do so that my variables are declared correctly using make

here is my makefile

 # target : dependencies
  2 cwork7 : main.o comp_disc.o print_res.o
  3     gcc main.o comp_disc.o print_res.o -Wall -o cwork7
  4
  5 main.o : main.c
  6     gcc -c main.c -Wall
  7
  8 comp_disc : comp_disc.c
  9     gcc -c comp_disc.c -Wall
 10
 11 print_res.o : print_res.c
 12     gcc -c print_res.c -Wall

my main.c

 5 #include <stdio.h>
  6 //functions prototypes
  7 void compute_discount(void);
  8 int print_results(void);
  9
 10
 11 //defined Gloabal var
 12 double Mdisc;
 13 double Cost_of_purchase;
 14 double DiscTot;
 15 double Sales_tax;
 16 double Total_price;
 17 char military;
 18
 19 int main (void) {
 20     //declare variables
 21
 22     //Cost of purchase
 23     printf("Cost of purchase?\t\t$");
 24     scanf ("%lf",&Cost_of_purchase);
 25
 26     //Military?
 27     printf("In military (y or n)?\t\t");
 28     scanf(" %c" ,&military);
 29
 30     //calling for functions
 31     compute_discount();
 32     print_results();
 33
 34 }
 35
 36

my print_res.c

  1 #include <stdio.h>
  2
  3 //function to print results
  4 int print_results(void){
  5
  6     //if input is y Y then use below, this is not dependant on if military only if the letter is accepted
  7     switch(military){
  8     case 'y':
  9     case 'Y':
 10         printf("Military discount (15%%): \t$%.2f\n", Mdisc);
 11         printf("Discounted total: \t\t$%.2f\n", DiscTot);
 12         printf("Sales tax (5%%): \t\t$%.2f\n", Sales_tax);
 13         printf("Total: \t\t\t\t$%.2f\n", Total_price);
 14         break;
 15     //less information is given when n or N is used
 16     case 'n':
 17     case 'N':
 18         printf("Sales tax (5%%): \t\t$%.2f\n", Sales_tax);
 19         printf("Total: \t\t\t\t$%.2f\n", Total_price);
 20         break;
 21 }
 22 return(0);
 23 }

and my comp_disc.c

1 #include <stdio.h>
  2
  3 //function to compute discount
  4 void compute_discount(void){
  5
  6     //compute military discount
  7     switch(military){
  8     case 'y':
  9     case 'Y':
 10         if(Cost_of_purchase > 150) {
 11             Mdisc = .15 * Cost_of_purchase;
 12         } else if (Cost_of_purchase < 150) {
 13             Mdisc = .10 * Cost_of_purchase;
 14         }
 15         break;
 16     case 'n':
 17     case 'N':
 18         Mdisc = 0;
 19         break;
 20     default:
 21         printf("Error: bad input\n");
 22 }
 23
 24     //cost minus military discount
 25     DiscTot = Cost_of_purchase - Mdisc;
 26     //sales tax
 27     Sales_tax = .05 * DiscTot;
 28     //Total Calculated
 29     Total_price = DiscTot + Sales_tax;
 30
 31 }

Please let me know what you think is the issue.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
Ivickt
  • 5
  • 4
  • 1
    Does this answer your question? [How do I share variables between different .c files?](https://stackoverflow.com/questions/1045501/how-do-i-share-variables-between-different-c-files) – Tsyvarev May 19 '21 at 15:34
  • Your `comp_disc.c` file seems to be syntactically incorrect. – arrowd May 19 '21 at 15:35

1 Answers1

0

This has nothing to do with the Makefile.

If you define the variables in all source file you get exactly what the linker says, multiple definitions of the same name. And if you drop them from the file you obviously get a compile error as you are using variables the compiler does not know about.

The simple solution is to keep the variables in main as-is, but to define them as extern in all other files, like extern double Cost_of_purchase; That tells the compiler the variable exists, but is already defined elsewhere, which solves the problem.

However, just don't use global variables. Pass your data to the functions.

struct acc_data {
    double Mdisc;
    double Cost_of_purchase;
    double DiscTot;
    double Sales_tax;
    double Total_price;
    char military;
}

int main(void)
{
    struct acc_data acc = { 0 };

    // init code skipped

    compute_discount(&acc);
    print_results(&acc);
}

void compute_discount(struct acc_data *acc)
{
    //same as before but prefix variables with acc->
    // example:
    acc->Total_price = 5000.0;
}

That gets rid of your original problem and improves your code somewhat.

Put the definition of the struct in a header file you include in all C files that use it.

koder
  • 2,038
  • 7
  • 10