-
July 13th, 2011, 03:43 AM
#1
Converting a C Program to Compile with C++
I've got an old project written in C and I changed the project to compile with the C++ compiler. All modules were renamed .CPP and the /TP flag is set in the Advanced Options to compile as C++.
I thought I would take advantage of the more robust C++ compiler.
I'm getting a number of LNK2019 and LNK2001 errors. Here are a couple of examples:
Code:
Filer3_321.obj : error LNK2019: unresolved external symbol "short __cdecl CheckDupLists(struct HWND__ *,char *,void * *,short)" (?CheckDupLists@@YAFPAUHWND__@@PADPAPAXF@Z) referenced in function "short __cdecl MergeListFile(char *,char *,struct HWND__ *)" (?MergeListFile@@YAFPAD0PAUHWND__@@@Z)
Listsup4_321.obj : error LNK2001: unresolved external symbol "short __cdecl CheckDupLists(struct HWND__ *,char *,void * *,short)" (?CheckDupLists@@YAFPAUHWND__@@PADPAPAXF@Z)
Listsup3_32.obj : error LNK2001: unresolved external symbol "short __cdecl CheckDupLists(struct HWND__ *,char *,void * *,short)" (?CheckDupLists@@YAFPAUHWND__@@PADPAPAXF@Z)
I also don't know why the compiler is adding a 1 to the end of the file name when creating the object file. The CPP file for the first example is filer3_32.cpp. I cleaned out all the old OBJ files before recompiling. That's not a major issue if the whole thing links OK.
CheckDupLists is in another module in the program that is included in the project. Each module that calls CheckDupLists has an extern declaration for the function. I have double checked and the extern declaration exactly matches the function definition.
The C version compiled without any issues. This should be obvious, I've figured these out before, but this one has me stumped. Any ideas?
Bill
-
July 13th, 2011, 11:16 AM
#2
Re: Converting a C Program to Compile with C++
Is the module (lib?) built as C or C++?
Even though you set the compiler to always compile as C++ there might be an extern "C" declaration somewhere .
-
July 13th, 2011, 01:59 PM
#3
Re: Converting a C Program to Compile with C++
One of the first things I did was remove all extern "C" references. There were a couple of modules already built as C++ and there were a number of externs declared that way to deal with them. Everything in the collection of projects has been changed from .c to .cpp and all are now compiled as C++. There are a couple of DLLs and several EXEs. The programs that are having the unresolved externals are EXEs. Bill
-
July 13th, 2011, 03:36 PM
#4
Re: Converting a C Program to Compile with C++
Is 'CheckDupLists' in one of the newly compiled DLL's? Or is it in some pre-compiled library already?
Viggy
-
July 13th, 2011, 05:25 PM
#5
Re: Converting a C Program to Compile with C++
No, it is a function in one of the modules compiled into the EXE.
Bill
-
July 13th, 2011, 10:10 PM
#6
Re: Converting a C Program to Compile with C++
Originally Posted by wdolson
Any ideas?
Bill
Code:
short __cdecl CheckDupLists(struct HWND__ *,char *,void * *,short)
The bottom line is that the linker cannot find a function with this definition.
Look in your source code and post the declaration and definition of that function here.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; July 13th, 2011 at 10:12 PM.
-
July 15th, 2011, 03:54 AM
#7
Re: Converting a C Program to Compile with C++
The reasons for the various link errors were many. In the case of CheckDupLists, there were two modules in the project, one ListSup2_32.cpp and the other LinkSup2_32.cpp. I only noticed the difference when opening ListSup2_32.cpp from different sub-projects appeared to open two different files.
There were also problems with the labyrinth of header files some previous program had set up with a bizarre array of #defines and conditional blocks of externs. Some functions were defined differently in different files and when compiled in C, they happened by chance to go down the right path to compile OK, but when I switched to CPP, this changed some of the conditionals and things got weird. This was the toughest to untangle.
I also found some global data declarations that should never have worked at all. The same global data structure was defined in a couple of files. I don't know why this hasn't caused bugs up until now.
This code is a mess. Has anyone ever seen how spinner controls and list boxes were populated in Windows 2? It's extremely non-intuitive. I've learned to appreciate the more modern Windows libraries much more.
Thanks for the help,
Bill
-
July 15th, 2011, 07:23 PM
#8
Re: Converting a C Program to Compile with C++
Originally Posted by wdolson
Some functions were defined differently in different files and when compiled in C, they happened by chance to go down the right path to compile OK
In 'C', functions using the same name, but have different parameters are perfectly valid. All 'C' cares about is the name of the function. You can compile all types of junk successfully in 'C' --the issue is that the program created this way exhibits undefined behaviour.
Here is an example:
Code:
int main()
{
int x = sqrt(98, 343, 234324);
}
In the example above, sqrt() is not declared, it takes 3 parameters, and it returns an int. This code compiles and links as 'C' with no errors. When you run it, that's when the weird things happen as the real sqrt() function looks nothing like that. You may get stack corruption errors or other errors.
Some C history -- when 'C' was first introduced, there were no such thing as function prototypes. In other words, you better call the function correctly, including assigning the return value to the correct type, else you would have a compiled program that has huge bugs.
Then came along the idea of the function prototype in 'C' to alleviate this issue. However, 'C' still accepts the stuff I posted above -- you can call any function any way you want (if you haven't declared it with a prototype), with the danger of runtime bugs if you didn't call the function correctly.
but when I switched to CPP, this changed some of the conditionals and things got weird. This was the toughest to untangle.
This is the big difference -- C++ checks prototypes since overloaded functions are valid in C++. If you're taking a C program written without using prototypes for functions, or generally coded by a hard-core C programmer who didn't care one whit about C++, then you will get these issues when converting from C to C++.
I also found some global data declarations that should never have worked at all. The same global data structure was defined in a couple of files. I don't know why this hasn't caused bugs up until now.
See above about what 'C' can do that C++ cannot and was not designed to do.
Regards,
Paul McKenzie
-
July 15th, 2011, 07:46 PM
#9
Re: Converting a C Program to Compile with C++
Originally Posted by Paul McKenzie
In 'C', functions using the same name, but have different parameters are perfectly valid. All 'C' cares about is the name of the function. You can compile all types of junk successfully in 'C' --the issue is that the program created this way exhibits undefined behaviour.
Here is an example:
Code:
int main()
{
int x = sqrt(98, 343, 234324);
}
In the example above, sqrt() is not declared, it takes 3 parameters, and it returns an int. This code compiles and links as 'C' with no errors. When you run it, that's when the weird things happen as the real sqrt() function looks nothing like that. You may get stack corruption errors or other errors.
Yes. Most of the functions were double prototyped, one set with no arguments and another with extern "C" for the modules already compiled in C++. But some functions were only prototyped with no arguments. There were about 8 different conditional compile flags that could be set and many were nested in the header files. It took me about an hour per header file to straighten it all out.
Some C history -- when 'C' was first introduced, there were no such thing as function prototypes. In other words, you better call the function correctly, including assigning the return value to the correct type, else you would have a compiled program that has huge bugs.
Then came along the idea of the function prototype in 'C' to alleviate this issue. However, 'C' still accepts the stuff I posted above -- you can call any function any way you want (if you haven't declared it with a prototype), with the danger of runtime bugs if you didn't call the function correctly.
I started programming in C just as prototyping was beginning to catch on in the late 1980s.
This is the big difference -- C++ checks prototypes since overloaded functions are valid in C++. If you're taking a C program written without using prototypes for functions, or generally coded by a hard-core C programmer who didn't care one whit about C++, then you will get these issues when converting from C to C++.
See above about what 'C' can do that C++ cannot and was not designed to do.
Regards,
Paul McKenzie
This is one of the reasons I changed the code to CPP files so I could get stronger prototyping checks by the compiler. The first version of this code was written before C++ existed. Even the C standard libraries hadn't been completely established yet. There are some home made string functions in there that could easily be replaced with standard C library calls. I've been replacing them if I'm working on that section of the code, but I haven't gone through and changed them all wholesale yet. That will wait for the replacement of the UI. The parts of internal code that will be saved are going to get brought up to date as much as I can. Bill
-
July 28th, 2011, 05:59 AM
#10
Re: Converting a C Program to Compile with C++
1. How the prototypes are declared in the 3 cpp files.
2. Are the corresponding definations exist?
3. Are the definations actually linked?
Nope
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|