【问题标题】:using Makefiles in c, declaring variables multiple definitions在c中使用Makefiles,声明变量多个定义
【发布时间】:2021-05-19 15:15:49
【问题描述】:

我在 c 中使用 makefile,我有三个文件,三个文件中的每一个都有每个变量的所有声明。所以我编译的时候是这样的。

/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

但是当我只在 main.c 上保留这些声明时,我得到了这个。

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;

所以我想知道我需要做什么才能使用 make 正确声明我的变量

这是我的生成文件

 # 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

我的 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

我的 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 }

还有我的 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 }

请让我知道您认为是什么问题。

【问题讨论】:

标签: c makefile


【解决方案1】:

这与 Makefile 无关。

如果你在所有源文件中定义变量,你会得到链接器所说的,同名的多个定义。如果你从文件中删除它们,你显然会得到一个编译错误,因为你正在使用编译器不知道的变量。

简单的解决方案是保持 main 中的变量原样,但在所有其他文件中将它们定义为 extern,例如 extern double Cost_of_purchase; 这告诉编译器该变量存在,但已经在其他地方定义,这解决了问题.

但是,不要使用全局变量。将您的数据传递给函数。

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;
}

这消除了您最初的问题并且在一定程度上改进了您的代码。

将结构的定义放在一个头文件中,你包含在所有使用它的 C 文件中。

【讨论】:

  • 哇,我不知道你能做到这一点,但这很有意义。非常感谢!
猜你喜欢
  • 2011-10-13
  • 2017-09-20
  • 2021-08-11
  • 2015-06-30
  • 2011-06-18
  • 1970-01-01
  • 2018-06-02
  • 2011-05-04
相关资源
最近更新 更多