当函数在头文件中列出时,未定义的引用,但如果我直接复制和粘贴代码则没问题

Undefined reference when a function is listed in a header file, but fine if I copy and paste code directly

本文关键字:如果 复制 没问题 代码 引用 文件 函数 未定义      更新时间:2023-10-16

我正在做一个大型的c++项目,它是私有的,所以我实际上不能分享源代码。我已经编译了大部分代码,但是在一个特定的文件中,有一个函数给我带来了不少麻烦。

我创建了一个简单的例子来说明问题所在。我们有:

WTPSHORT.H

#ifndef WTP_H
#define WTP_H 1
#define  VERSION  "Version 2.1"
#define  DATE     "Nov., 2001"
/* ANSI C header files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <fcntl.h>
#include <ctype.h>
#define TRUE  1
#define FALSE 0

/************  Data structures for Water Treatment Plant ***************/
struct Effluent {    /******  Data Packet for All Unit Processes *******/
                 /* Operating data:                                */
  double  DegK;      /*   Temperature                          (Deg K) */
  double  Flow;      /*   Average flow                           (MGD) */
  double  Peak;      /*   Max hourly flow                        (MDG) */
                 /* Unit process counters:                         */
  short   cl2cnt;    /*   Number of times chlorine added.              */
                 /* Measurable Water Quality Parameters:           */
  double  pH;        /*   [H+]=pow(10,-pH)                         (-) */
  /* More variable definitions go here */
  double beta_br;   /* Constant for chlorine to bromine reactivity ratio */
  double time_step; /* Time step (hrs) */
};                   /************  End of struct Effluent  ************/

                              /*****************************************/
struct ProcessTrain {         /* Control Structure for Process Train   */
  struct UnitProcess  *head;  /*   First UnitProcess in ProcessTrain   */
  struct UnitProcess  *null;  /*   Always NULL                         */
  struct UnitProcess  *tail;  /*   Last UnitProcess in ProcessTrain    */
  char       file_name[120];  /*   Full path and extension             */
  };                          /*****************************************/

struct UnitProcess {         /********** Treatment Process ***************/
  struct UnitProcess *next;  /* Double Linked list                       */
  struct UnitProcess *prev;  /*   "      "     "                         */
  short               type;  /* Defined unit process types               */
  short               pad;   /* Maintain 32 bit alinment of pointers     */
  union {                    /* Design and operating parameters:          */
    void                 *ptr;
    struct Influent      *influent;
    struct Mechdbp       *mechdbp;                   //FOR MECH MODEL
    struct Alum          *alum;
     struct Gac           *gac;
    struct Filter        *filter;
    struct Basin         *basin;
//  struct Membrane      *membrane;
    struct Mfuf          *mfuf;
    struct Nf            *nf;
    struct Iron          *iron;
    struct chemical      *chemical;
    struct clo2          *clo2;
    struct lime          *lime;
  /*struct WTP_effluent  *wtp_effluent;  No longer needed - WJS, 11/98 */
    struct Avg_tap       *avg_tap;
    struct End_of_system *end_of_system;
    } data;
  struct Effluent     eff;
  };
struct Influent {      /* Raw Water Data                          */
  double  pH;          /* (-)                                     */
  double  temp;        /* Average temperature (C)                 */
  double  low_temp;    /* Low temperature for disinfection (C)    */
  double  toc;         /* (mg/L)                                  */
  double  uv254;       /* (1/cm)                                  */
  double  bromide;     /* (mg/L)                                  */
  double  alkalinity;  /* (mg/L as CaCO3)                         */
  double  calcium;     /* Calcium Hardness (mg/L as CaCO3)        */
  double  hardness;    /* Total   Hardness (mg/L as CaCO3)        */
  double  nh3;         /* Ammonia (mg/L as N)                     */
  double  ntu;         /* Turbidity                               */
  double  crypto_req;  /* Crypto Log removal + Log Inact. required*/
  double  clo2_crypto_ct_mult; /* Multiplier */
  double  peak_flow;   /* Peak Hourly Flow for disinfection (MGD) */
  double  avg_flow;    /* Average Flow (MGD)                      */
  int     swflag;      /* TRUE=Surface Water; FALSE=Ground Water  */
//  char    *run_name;
};         
void s1_s2_est(struct UnitProcess *unit);              
/* define(s) for UnitProcess.type */
#define  VACANT                 0
#define  INFLUENT               1
#define  RAPID_MIX              2
#define  SLOW_MIX               3
#define  SETTLING_BASIN         4
#define  FILTER                 5
#define  BASIN                  6
#define  CONTACT_TANK           7
#define  CLEARWELL              8
#define  O3_CONTACTOR           9 
#define  GAC                    10
#define  MFUF_UP                11
#define  NF_UP                  12
#endif

项目中有两个源文件:

s1s2_est.c

/* s1s2_est.c --  December, 2000*/
#include "WTPSHORT.H"
void s1_s2_est(struct UnitProcess *unit)
{
    double toc, uva, s1_0, s2h_0, s2star_0, s2t_0, s1_f, s2h_f, s2star_f, s2t_f, H; 
    struct Effluent *eff;
    eff = &unit->eff;
    /* Get these inputs */
    toc      = eff->TOC;
    uva      = eff->UV;
    s1_0     = eff->s1;
    s2h_0    = eff->s2h;
    s2star_0 = eff->s2_star;
    H        = pow(10.0, -eff->pH);

    s2t_0 = s2h_0 + s2star_0;
    s1_f    = s1_0;
    s2t_f   = s2t_0;
    s2star_f    = s2star_0;
    s2h_f   = s2h_0;
    if(eff->s1_s2_estflag == 'C')
      {
       /* Safety check */
       if (toc < 0.0) toc = 0.0;
       if (uva < 0.0) uva = 0.0;
       s1_f  = 5.05 * pow(toc, 0.57) * pow(uva, 0.54);
       s2t_f = 13.1 * pow(toc, 0.38) * pow(uva, 0.40);
       /* No increases in the S values allowed */
       if(s1_f  > s1_0 ) s1_f  = s1_0;
       if(s2t_f > s2t_0) s2t_f = s2t_0;
       /* Speciate S2 */
       s2h_f    = s2t_f * eff->k21r * H / (eff->k21f + eff->k21r * H);
       s2star_f = s2t_f * eff->k21f     / (eff->k21f + eff->k21r * H);
      }   
    if(eff->s1_s2_estflag != 'C' && unit->type == INFLUENT)
      {/* Speciate S2 in raw water*/  
       s2h_f    = s2t_f * eff->k21r * H / (eff->k21f + eff->k21r * H);
       s2star_f = s2t_f * eff->k21f     / (eff->k21f + eff->k21r * H);
      }
    /* Update Effluent data structure */
    eff->s1      = s1_f;
    eff->s2h     = s2h_f;
    eff->s2_star = s2star_f;
}/* End subroutine "s1_s2_est()"*/

main.cpp

#include <stdio.h>
#include "WTPSHORT.H"
int main(int argc, char **argv)
{
    UnitProcess *myunit;
    s1_s2_est(myunit);
    printf("donen");
    return 0;
}

当编译和链接时,我看到这个错误:

C:WINDOWSsystem32cmd.exe /C "C:/MinGW/bin/mingw32-make.exe -j8 SHELL=cmd.exe -e -f  Makefile"
       "----------Building project:[ simple - Debug ]----------"
    mingw32-make.exe[1]: Entering directory         'C:/Users/joka0958/Desktop/wtp/compiledwtp/simple'
C:/MinGW/bin/g++.exe  -c      "C:/Users/joka0958/Desktop/wtp/compiledwtp/simple/main.cpp" -g -O0 -Wall  -o ./Debug/main.cpp.o -I. -I.
C:/MinGW/bin/gcc.exe -c  "C:/Users/joka0958/Desktop/wtp/compiledwtp/simple/s1s2_est.c" -g -O0 -Wall  -o ./Debug/s1s2_est.c.o -I. -I.
C:/Users/joka0958/Desktop/wtp/compiledwtp/simple/main.cpp: In function 'int main(int, char**)':
C:/Users/joka0958/Desktop/wtp/compiledwtp/simple/main.cpp:7:22: warning: 'myunit' is used uninitialized in this function [-Wuninitialized]
     s1_s2_est(myunit);
                      ^
C:/MinGW/bin/g++.exe -o ./Debug/simple @"simple.txt" -L.
./Debug/main.cpp.o: In function `main':
C:/Users/joka0958/Desktop/wtp/compiledwtp/simple/main.cpp:7: undefined reference to `s1_s2_est(UnitProcess*)'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[1]:  [Debug/simple] Error 1
mingw32-make.exe:  [All] Error 2
simple.mk:78: recipe for target 'Debug/simple' failed
mingw32-make.exe[1]: Leaving directory 'C:/Users/joka0958/Desktop/wtp/compiledwtp/simple'
Makefile:4: recipe for target 'All' failed
2 errors, 1 warnings

那么问题是:为什么我得到一个未定义的引用?

我意识到这是一个可能掩盖另一个问题的错误,但我真的已经用尽了所有的可能性,在我的脑海中,什么可能导致这个问题。请注意,这是一个更大项目的一部分,其中许多其他函数可以正确编译和链接。

顺便说一下,我在Windows 10上使用Codelite与MinGW编译器。

很抱歉这个问题引起了大家的恐慌。原来在这个文件中有c++特有的函数,但是因为这个文件是以*. C命名的,所以codelite默认为C编译器来实际编译这个特定的源文件。一旦我更改了文件名,代码就编译成功了。谢谢你所有有用的建议!

相关文章: