Undefined symbol error

Hi, I've recently taken over a project and therefore I am not completely familiar with it - however, I've encountered an undefined symbol error on the line:

DatabaseName = tAccountsDB->DatabaseName;

and the error:

[C++ Error] TYearEndOprType.cpp(27): E2451 Undefined symbol 'tAccountsDB'


Within a different class hovering the same line of code indicates that it pulls tAccountsDB from the main, yet this one cannot find it. Both classes include main.h so I'm stumped.

Any suggestions?

Last edited on
It looks like tAccountsDB is a pointer to a class (or struct). Where specifically is tAccountsDB defined? It needs to be a class variable, global variable, local variable, static variable, or an argument to the function--somehow in scope--in order to be accessible at line 27 where the error is.

Without more context, we can't really tell you why it's not defined. Why don't you post main.h and TYearEndOprType.cpp (or at least up to and including the function that's not compiling)?

Hi,

This is the TYearEndOprType.cpp up to and including the function that contains the issue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

//#include "TYearEndOprType.h" //redefined in dataaccess
#include "DataAccess.h"
#include "main.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TTYearEndOprType *)
{
        new TTYearEndOprType(NULL);
}
//---------------------------------------------------------------------------
__fastcall TTYearEndOprType::TTYearEndOprType(TComponent* Owner)
        : TTable(Owner)
{
    DatabaseName = tAccountsDB->DatabaseName;
    TableName = AnsiString("YEAR_END_OPR_TYPE");
    IndexFieldNames = AnsiString("YEAR_END_OPR_TYPE_CODE");
    //MasterFields = AnsiString("YEAR_END_OPR_TYPE_CODE");
    OnUpdateError = ERRORBOX;
    Active = True;      // open the data source
}
//--------------------------------------------------------------------------- 


The main file is huge, however near the top of the file after includes/pragma etc is:

TAccountsDB* tAccountsDB;

Which I believe is the variable its supposed to be using in the TYearEndOprType.cpp.
Hovering the "TAccountsDB*" section points me to "DataAccess.h" which has:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//---------------------------------------------------------------------------
#ifndef DataAccessH
#define DataAccessH

//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <Db.hpp>
//suyu, added Oct.16.00 for including the header file of DecisionQuery
#include <mxtables.hpp>

#include "datatype.h"
//#include "Dialogs.h" // functions defined in MTAL_Accounts
//#include "globalfunctions.h" //better independent
#include "ErrorForm.h"


//---------------------------------------------------------------------------
class PACKAGE TAccountsDB : public TDatabase
{
private:
         AnsiString dbPath;      // Path of Db only
         AnsiString dbName;      // Name of Db only
         AnsiString sourcePath;  // Full path of database on server
         AnsiString targetPath;
         AnsiString szMesg;
         AnsiString programPath;
         AnsiString DBDriverLetterPath;
         ///////////////////////////
protected:
public:
    __fastcall TAccountsDB(TComponent* Owner);
    __fastcall TAccountsDB(TComponent* Owner, AnsiString szAliasName);
__published:
    void __fastcall AddNewAlias(AnsiString szDataLocation, AnsiString szAliasName);
    void __fastcall DeleteAlias(/*AnsiString szDataLocation,*/ AnsiString szAliasName);
    bool __fastcall ChangeAlias(AnsiString szAliasName);
    void __fastcall Connect();
    void __fastcall Disconnect();

    void __fastcall dbInfo();//void dbInfo();
    void __fastcall setSourcePath();//AnsiString setSourcePath();
    void __fastcall setSourcePath(AnsiString varSourcePath);

    AnsiString __fastcall getSourcePath();//AnsiString getSourcePath();
    AnsiString __fastcall getDBPath();//AnsiString getDBPath() { return dbPath; };
    AnsiString __fastcall getDBName();//AnsiString getDBName() { return dbName; };
    void __fastcall setDB();//void setDB();
    bool __fastcall setDBPath();
    void __fastcall setProgramPath();
    AnsiString __fastcall getProgramPath();
    AnsiString __fastcall GetDBDriverLetterPath();  // R 25/03/10 added
    ///////////////////////////////////////
};

//--------------------------------------------------------------------------- 


Does this help at all? Thanks
Last edited on
The main file is huge, however near the top of the file after includes/pragma etc is:

 
TAccountsDB* tAccountsDB;

Assuming that by "The main file" you mean "main.h", then so long as you #include that file either directly or nested inside some other header which you do include, then all should be well.

The question then is this: in the file which gives you the error - do you have the right #includes?

Another question arises from the opening post,
Hi, I've recently taken over a project and therefore I am not completely familiar with it - however, I've encountered an undefined symbol error on the line:

Was this an existing problem which you were called in to fix, or was everything fine until you tried to build it. Or was it fine until you changed something?

Also, before you get this error,
[C++ Error] TYearEndOprType.cpp(27): E2451 Undefined symbol 'tAccountsDB'
are there any other messages - for example a failure to find a header file or some other message which might have this as a later consequence?
The main file is huge, however near the top of the file after includes/pragma etc is:

TAccountsDB* tAccountsDB;


OK, the file is huge. However, giving us 1 line of text (and is it a complete line? I assume it is, but i don't know for sure) out of context does not help a lot. Why don't you post the main file through the line you quote?

By the way, Everything that @Chervil wrote I was also thinking. Most significantly, is "the main file" main.h?
Hi, thanks for the advice - and apologies! The TAccountsDB* tAccountsDB; line is in "main.cpp". However, there is a extern TAccountsDB* tAccountsDB; line within "main.h", quite a way through.

Also, apologies for not posting the code - it had approx. ~150 includes, etc, which I thought would be overkill to post before I reached the line in the .cpp, which I didn't feel were helpful.

To answer, the existing problem question: it's complicated. It's an existing problem, but the staff who developed this before me have left, and also have left little in the way of documentation... so take that as you will. But, these issues aren't from anything I have changed. In it's current state, I can't even run it to debug it - it's also rather substantial.

I do get other warnings before the errors
[C++ Warning] TYearEndOprType.cpp(3): W8058 Cannot create pre-compiled header: write failed
however I didn't think this would be much of an issue as of the moment. This happens for all .cpp files that it's gone through up to the issue.

I did notice something - the TYearEndOprType.cpp file does not have a header file; however it does have in "DataAccess.h":

1
2
3
4
5
6
7
8
9
class PACKAGE TTYearEndOprType : public TTable
{
private:
protected:
public:
        __fastcall TTYearEndOprType(TComponent* Owner);
        __fastcall TTYearEndOprType(TComponent* Owner, TDataSource* objDS);
__published:
};


which I believe should be valid. "Main.h" includes "User.h", and "User.h" includes "DataAccess.h"; so in a way I believe this should be acceptable.

EDIT: I think I've managed to fix this issue, for whatever reason it was looking at the wrong "main.h" file... well, onto the next error now! A multiple declaration issue, if you must know. Wish me luck.
Last edited on
Glad you got to the bottom of this.

for whatever reason it was looking at the wrong "main.h" file
I'm assuming you're using C++ builder (hopefully in an up-to-date version). One problem I've sometimes encountered is when copying a project. There are probably specific ways of doing this properly, but occasionally I've found I have the project file from one project trying to include files from a different, earlier version of a similar project. It can give rise to baffling effects.

There's something about the warning W8058 here, don't know if it sheds any light on the issue:
https://stackoverflow.com/questions/956727/why-is-cbuilder-failing-to-create-pre-compiled-headers
But I think it shouldn't cause anything to break completely, it's more of minor irritation.
Thanks for the help, it got me thinking along the right lines anyhow.

And yes, I am; of which I haven't used C++ builder before (only a lot of Visual Studio in previous projects) - I am however using C++ Builder 6, which seems to be a little dated now (just what was installed on what I was given)... I'll have to see about upgrading. With being a newbie to C++ builder I'm yet to learn the intricacies such as that! Thanks for the advice though.

Yes, as far as I'm aware it's just irritation - it would be nice to have them precompiled but at the moment I'm more focused on it actually compiling first never mind being precompiled! Once I'm further I'll have a read of those posts and see if I can sort it out.
C++ Builder 6

Yes that is a bit dated indeed.

If you're working on something within a business or work environment, then not rocking the boat and staying with a known but idiosyncratic system may be reasonable, upgrading is something which needs to be done in a planned and controlled way.

For less critical projects, you can get a personal-use starter edition from a 2016 version free of charge. But for business use you may need a paid version.
https://www.embarcadero.com/free-tools

Topic archived. No new replies allowed.