Jump to content

  • Log In with Google      Sign In   
  • Create Account

SafeCracker program help!


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 mKatz   Members   -  Reputation: 732

Like
-1Likes
Like

Posted 06 August 2012 - 12:44 PM

program..
// learn.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "safestuff.cpp"
#include "SafeCracker.cpp"
#include <string>
using namespace std;
int main()
{
cout << "Suprise, suprise!" << endl;
cout << "The combination is (once again)" <<endl;
  cout << SafeCracker(12)<<endl;
system("pause");

return 0;
}

safestuff.cpp

#include "stdafx.h"
#include <string>
using namespace std;
#ifndef SAFESTUFF_H_INCLUDED
#define SAFESTUFF_H_INCLUDED
string SafeCracker(int SafeID);
#endif // SAFESTUFF_H_INCLUDED

SafeCracker.cpp

#include "stdafx.h"
#include <string>
using namespace std;
string SafeCracker(int SafeID)
{
return "13-26-16";
}

This is the error code I do not understand, if you could help me out it would be much appreciated!

1>------ Build started: Project: learn, Configuration: Debug Win32 ------
1>SafeCracker.obj : error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl SafeCracker(int)" (?SafeCracker@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z) already defined in learn.obj
1>C:\Users\JonBecher\documents\visual studio 2012\Projects\learn\Debug\learn.exe : fatal error LNK1169: one or more multiply defined symbols found
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Sponsor:

#2 SimonForsman   Crossbones+   -  Reputation: 6305

Like
3Likes
Like

Posted 06 August 2012 - 12:49 PM

rename safestuff.cpp safecracker.h , include it in your main cpp file and remove the include for safecracker.cpp
I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

#3 mKatz   Members   -  Reputation: 732

Like
0Likes
Like

Posted 06 August 2012 - 12:55 PM

Thank you so much! I appreciate it!

#4 rip-off   Moderators   -  Reputation: 8726

Like
7Likes
Like

Posted 06 August 2012 - 01:14 PM

To explain further, C++ conceptually has a three stage process to go from source to executable. The first is pre-processing (more or less all the lines beginning with #), then the compiler and finally the linker.

First, we must understand the difference between source files (typically .cpp) and header files (typically .h or .hpp). Source files are compiled, header files are not. The contents of header files may be compiled, as we shall see later. The selection of source files to be compiled is explicitly listed by the build tool, or computed by the build tool. For example, your IDE automatically selects all .cpp files to be compiled. Each source file is compiled by itself, independently of the others.

The first step is to pre-process each source file. This involves the pre-processor finding directives such as #include, #define and evaluating the contents of #if, #else etc. This is where header files come in - every #include directive is an instruction for the preprocessor to replace that line with the contents of the referenced file. That is, a header file will literally by copy/pasted into each source file that includes it. The output of the preprocessor is called a "translation unit".

Each translation unit is then compiled. The compiler does the ordinary work of ensuring you are following the syntax of C++, that you abide by its type system etc, and outputs a so-called "object file". Note that this terminology is unrelated to "object orientation", an object here means something akin to a function or global variable. Object files might end in a .o or .obj, depending on the tools you use.

Finally, the linker is the step that joins each of these translation units into an executable. Objects that are not defined in a given translation unit must be found in exactly one other translation unit, or the linker will give up because it cannot determine which one to use.

Using this information, we can understand what happened in this situation and the rules to prevent this re-occurring. What happened was that your IDE compiled three source files, learn.cpp, safestuff.cpp and SafeCracker.cpp. Because you #included the contents of SafeCracker.cpp into learn.cpp, there was two copies of the "SafeCracker" function emitted in the object files - one in learn.obj and the other in SafeCracker.obj.

When the linker went to make an executable from this, it found two objects for the "SafeCracker" function where there should only have been one. Thus, it issued a multiple defintion error:

fatal error LNK1169: one or more multiply defined symbols found

Another way to get this error would have been to have a second implementation of SafeCracker in another file.

SimonForsman's advice avoids this error by causing the SafeCracker function to be emitted only in SafeCracker.obj, but not in learn.obj. Thus, when the program is linked there are no duplicate symbols, there is one main() symbol and one SafeCracker symbol (ignoring the standard library ones), and everthing is correct.

One important lesson from the above is that #including a source file is always* the wrong thing to do! You will get multiple definitions if your source file has any definitions (which it should, otherwise it isn't doing anything). Likewise, header files should not contain definitions, because they are likely to be #included more than once and will again lead to multiple definitions.

Note that there is a final issue, but it is minor. Your header file should be completely enclosed by the include guard. Thus, your new SafeCracker.h file should look like this:
#ifndef SAFESTUFF_H_INCLUDED
#define SAFESTUFF_H_INCLUDED

#include <string>
using namespace std;

string SafeCracker(int SafeID);

#endif // SAFESTUFF_H_INCLUDED
Note that you do not #include the "stdafx.h" in a header file.

* There are advanced techniques that (ab)use this, but for the moment pretend this is a hard rule

#5 mKatz   Members   -  Reputation: 732

Like
0Likes
Like

Posted 06 August 2012 - 01:21 PM

Thank you rip-off for going in depth it is much appreciated and is a great learning tool!

#6 mKatz   Members   -  Reputation: 732

Like
-1Likes
Like

Posted 06 August 2012 - 01:26 PM

This topic is done.

Edited by JonBMN, 06 August 2012 - 01:35 PM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS