Thread: The so annoying LNK2005... please help!

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    10

    The so annoying LNK2005... please help!

    Heya folks, this is my first post in here, hope you gurus out there can help me out:

    I'm programming a very basic web server (college task in networking).

    my project currently has 3 files:

    webserver.cpp - Which contains the main, and various socket related functions.

    webserver-engine.cpp - Which contains all HTTP protocol parsing functions, and other functions which are responsible for setting up HTTP responses from the server.

    webserver-engine.h - Which contains all webserver-engine.cpp functions declarations, plus all of the project's consts and structs. This file is #included in both the webserver-engine.cpp and webserver.cpp files above.

    Problem is that I get the following errors:

    Code:
    Error	26	fatal error LNK1169: one or more multiply defined symbols found	C:\Users\Mikey Shiran\Documents\Visual Studio 2008\Projects\Semester 3\Comm\WebServer\Debug\WebServer.exe	1
    Error	24	error LNK2005: "char const * const SERVER_NAME" (?SERVER_NAME@@3PBDB) already defined in webserver.obj	webserver-engine.obj
    Error	25	error LNK2005: "char const * const HTTP_VERSION" (?HTTP_VERSION@@3PBDB) already defined in webserver.obj	webserver-engine.obj
    Error	23	error LNK2005: "char const * const HOME_DIR" (?HOME_DIR@@3PBDB) already defined in webserver.obj	webserver-engine.obj
    Error	22	error LNK2005: "char const * * MONTH" (?MONTH@@3PAPBDA) already defined in webserver.obj	webserver-engine.obj
    Error	21	error LNK2005: "char const * * DAY" (?DAY@@3PAPBDA) already defined in webserver.obj	webserver-engine.obj
    Error	20	error LNK2005: "char const * * CONTENT_TYPE" (?CONTENT_TYPE@@3PAPBDA) already defined in webserver.obj	webserver-engine.obj

    webserver-engine.h looks likes this:
    Code:
    #ifndef _WEBSERVER_ENGINE_H_
    #define _WEBSERVER_ENGINE_H_
    
    #include <iostream>
    using namespace std;
    #include <stdio.h>
    #include <winsock2.h>
    
    const int MAX_BUF_SIZE = 256;
    
    typedef struct contentInfo {
    	int typeIndx;
    	int statusIndx;
    	int length;
    	char* requestedPath;
    	FILE* currFile;
    	char shortData[MAX_BUF_SIZE];
    	bool isHeadReq;
    	bool readFile;
    	bool headerSent;
    } ContentInfo;
    
    struct SocketWhat
    {
    	SOCKET id;		// Socket handle
    	int	whatR;		// Receiving?
    	int	whatS;		// Sending?
    	char buffer[MAX_BUF_SIZE];
    	int len;
    	bool closeCon;
    	contentInfo content;
    };
    
    typedef struct status {
    	int code;
    	char* msg;
    	char* htmlCode;
    } Status;
    
    const int TYPE_UNKNOWN = -1;
    const int TYPE_HTML = 0;
    const int TYPE_CSS = 1;
    const int TYPE_JPG = 2;
    const int TYPE_PNG = 3;
    const int TYPE_GIF = 4;
    
    const char* CONTENT_TYPE[5] = {
    	"text/html", 
    	"text/css",
    	"image/jpeg",
    	"image/png",
    	"image/gif"
    };
    
    const int STATUS_ERR_NOT_FOUND = 0;
    const int STATUS_ERR_NOT_IMPLEMENTED = 1;
    const int STATUS_OK = 2;
    
    const Status HTTP_STATUS[3] = { 
    	{404, "Not Found", 
    	 /* MAKE SURE THIS IS NOT LONGER THAN MAX_BUF_SIZE */
    	 "<html><title>ERROR 404 - File Not Found</title><body><h2>ERROR 404 - The file you requested was not found on this server.</h2></body></html>"},
    
    	{501, "Not Implemented", 
    	 /* MAKE SURE THIS IS NOT LONGER THAN MAX_BUF_SIZE */
    	 "<html><title>ERROR 501 - Request Type Not Implemented</title><body><h2>ERROR 501 - Your request is not supported by this server</h2></body></html>"},
    
    	{200, "OK", NULL}
    };
    
    const int MAX_DATE_LEN = 32;
    const char* DAY[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    const char* MONTH[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    
    const char* HOME_DIR = "D:/WebServer";
    const char* SERVER_NAME = "MSCK WebServer v0.1";
    const char* HTTP_VERSION = "1.1";
    const int DEFAULT_BUF_SIZE = 512;
    const int MAX_CONTENT_HEAD_SIZE = 140;
    
    char* parseReqGenerateHeader(struct SocketWhat& sock);
    char* generateHeader(ContentInfo& content);
    char* getTimeAndDateAsStr();
    int getContentTypeIndx(char* filePath);
    void strToLower(char* src);
    char* getCompleteFilePath(char* path);
    long getFileSize(FILE* filePntr);
    void cleanContent(ContentInfo& content);
    void setErrorContent(ContentInfo& content, int statusErr);
    char* findInHeader(SocketWhat& sock, char* str);
    void printTokens(char* str, char* delim);
    
    #endif
    And i've checked that both the engine and main files aren't defining the above variables inside them.

    Any ideas how to solve this?

    Thanks alot!

    Mikey

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Any const that isn't a simple integer (or an integer that has it's address taken) will be stored in the data section with a public name.

    For example these:
    Code:
    const char* HOME_DIR = "D:/WebServer";
    const char* SERVER_NAME = "MSCK WebServer v0.1";
    const char* HTTP_VERSION = "1.1";
    So, use extern const char *xxx; in the code. Then have ONE file (eg. "constants.cpp") that set the value of these type of constants.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    10
    Thanks for the reply!

    So I should put them as "extern" in the engine.h file (instead of what I just posted), and have another cpp that sets their values?

    Same goes for those const string arrays?

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Mikey_S View Post
    Thanks for the reply!

    So I should put them as "extern" in the engine.h file (instead of what I just posted), and have another cpp that sets their values?

    Same goes for those const string arrays?
    Yes.

    The key is to SET the constants only once.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    58
    i'm facing problem like u.

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    10
    mat,

    I just want to understand:

    When I include "webserver-engine.h" and say when the compiler enters the file it enters first (whether it's webserver.cpp or webserver-engine) it sets all those data section consts once... but when does the compiler thinks it defines those once more?

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You include it in webserver.cpp -- that's one.
    You include it in webserver-engine.cpp -- that's two.

    Notice that files are compiled separately, so inclusion guards won't help you here. (That's only for a header being included twice in the same file.)

  8. #8
    Registered User
    Join Date
    Jan 2009
    Posts
    10
    Any chance you guys can link me up to a source explaining all this information more thoroughly?

    I just can't quite understand something:
    if the guard works only if I include the header file in the same file twice, how come the compiler doesn't produce linker error for the functions declaration? and the other variables?

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Mikey_S View Post
    Any chance you guys can link me up to a source explaining all this information more thoroughly?

    I just can't quite understand something:
    if the guard works only if I include the header file in the same file twice, how come the compiler doesn't produce linker error for the functions declaration? and the other variables?

    The #include is simply a way to save some copy'n'pasting - it allows you to have ONE file that to the compiler appears to be part of the source code.

    Function declarations do not produce anything - they are just declarations "there is a function somewhere else, and it takes these parameters and return this type".

    Also, integer constants that do not have their address taken will most of the time not have any storage - so there's nothing for the linker to worry about.

    Now, if we have these two files:
    Code:
    // foo.c
    const char *foo = "Some string";
    
    // bar.c
    const char *foo = "Some string";
    So, this would give the warning - and when you have a include file, you are doing the same thing.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    Jan 2009
    Posts
    10
    What do you mean by "integer constants that do not have their address taken"?

    And how come the compiler won't produce an error for:

    Code:
    const Status HTTP_STATUS[3] = { 
    	{404, "Not Found", 
    	 /* MAKE SURE THIS IS NOT LONGER THAN MAX_BUF_SIZE */
    	 "<html><title>ERROR 404 - File Not Found</title><body><h2>ERROR 404 - The file you requested was not found on this server.</h2></body></html>"}
    
    	{501, "Not Implemented", 
    	 /* MAKE SURE THIS IS NOT LONGER THAN MAX_BUF_SIZE */
    	 "<html><title>ERROR 501 - Request Type Not Implemented</title><body><h2>ERROR 501 - Your request is not supported by this server</h2></body></html>"},
    
    	{200, "OK", NULL}
    };
    And I don't need to have this as extern?


    So basically when I compile a file (files are compiled seperately), in the first process, the compiler goes over my cpp file, and every time it sees an "#include", it simply "copy and pastes" it's content.
    Same goes for all other files in the project.

    Does that mean that if I've included a header file in two seperate cpp files, my final "merged" file will include 2 copies of the same function/consts declarations?

    again, really appreciate your help. This subject was always kind of a pain for me.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Mikey_S View Post
    What do you mean by "integer constants that do not have their address taken"?
    If the compiler sees a variable referenced that is declared const, then it takes that variables value and pastes it in the code instead of the variable name.

    This code...
    Code:
    const int x = 10;
    int main() { std::cout << x; }
    ...will probably look like this before being turned into machine code:
    Code:
    int main() { std::cout << 10; }
    Because the variable is const, the compiler knows its value will never change and thus optimizes it.

    And how come the compiler won't produce an error for:

    Code:
    const Status HTTP_STATUS[3] = { 
    	{404, "Not Found", 
    	 /* MAKE SURE THIS IS NOT LONGER THAN MAX_BUF_SIZE */
    	 "<html><title>ERROR 404 - File Not Found</title><body><h2>ERROR 404 - The file you requested was not found on this server.</h2></body></html>"}
    
    	{501, "Not Implemented", 
    	 /* MAKE SURE THIS IS NOT LONGER THAN MAX_BUF_SIZE */
    	 "<html><title>ERROR 501 - Request Type Not Implemented</title><body><h2>ERROR 501 - Your request is not supported by this server</h2></body></html>"},
    
    	{200, "OK", NULL}
    };
    And I don't need to have this as extern?
    For the same reason as above.

    So basically when I compile a file (files are compiled seperately), in the first process, the compiler goes over my cpp file, and every time it sees an "#include", it simply "copy and pastes" it's content.
    Same goes for all other files in the project.

    Does that mean that if I've included a header file in two seperate cpp files, my final "merged" file will include 2 copies of the same function/consts declarations?

    again, really appreciate your help. This subject was always kind of a pain for me.
    Yes and no.
    The compiler just parses source files and generates code for it.
    Then the linker will come in and finish the process. Here's where things go wrong when you have multiple functions or variables with the same name.
    Because a function can call a function is another source file, or reference a global variable in another, how is the linker supposed to know which one among the many?

    Declarations are only there for the compiler. They provide the compiler with information and is discarded later. So they won't ever be seen by the linker. But multiple variables will...

    Code:
    Sample1.h:
    int x;
    
    Sample1.cpp:
    #include "Sample1.h"
    void foo() { std::cout << x; }
    
    Sample2.cpp:
    #include "Sample1.h"
    void foo2() { std::cout << x; }
    
    Linker code:
    int x;
    int x;
    void foo() { std::cout << x; }
    void foo2() { std::cout << x; }
    OOPS!
    Code:
    Sample2.h:
    const int x = 5;
    
    Sample3.cpp:
    #include "Sample2.h"
    void foo() { std::cout << x; }
    
    Sample4.cpp:
    #include "Sample2.h"
    void foo2() { std::cout << x; }
    
    Linker code:
    void foo() { std::cout << 5; }
    void foo2() { std::cout << 5; }
    OK!
    Last edited by Elysia; 01-31-2009 at 02:05 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Jan 2009
    Posts
    10
    Ok, things are getting clearer now.

    So basically consts act like some sort of declaration for simple types like int...
    Why doesn't it work the same way for char* or an array of char*
    and on the other hand, IT DOES work on a struct CONTAINING char* like the one I posted in my last post?

    that is:

    Code:
    const Status HTTP_STATUS[3] = { 
    	{404, "Not Found", 
    	 /* MAKE SURE THIS IS NOT LONGER THAN MAX_BUF_SIZE */
    	 "<html><title>ERROR 404 - File Not Found</title><body><h2>ERROR 404 - The file you requested was not found on this server.</h2></body></html>"}
    
    	{501, "Not Implemented", 
    	 /* MAKE SURE THIS IS NOT LONGER THAN MAX_BUF_SIZE */
    	 "<html><title>ERROR 501 - Request Type Not Implemented</title><body><h2>ERROR 501 - Your request is not supported by this server</h2></body></html>"},
    
    	{200, "OK", NULL}
    };
    Sorry, I just can't totally grasp it yet...

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    const char* is a non-constant variable that points to constant data.
    In other words, you can change the variable itself, but not what it points to.
    Therefore, its value can change and the compiler cannot assume its data will not change and cannot perform the optimization.

    As for the struct... well, the struct itself is constant, so that means none of its members may change either! Effectively, it makes them all const, too. Because if one member changes, the contents of the struct itself changes and that goes against const!

    Makes sense?

    const char* p -> a pointer to const char.
    char* p const -> a const pointer to char.
    Last edited by Elysia; 01-31-2009 at 03:05 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    Jan 2009
    Posts
    10
    Oh cool...

    I think I got (finally!)...

    So I can avoid the extern by using the following code:

    Code:
    const char* const foo = "Some string";
    That way (if im not mistaken) both the pointer and the variable are declared as constants,
    correct?

  15. #15
    System Novice siavoshkc's Avatar
    Join Date
    Jan 2006
    Location
    Tehran
    Posts
    1,246
    You are trying to define a "Constant pointer to a Constant value". Why?
    Learn C++ (C++ Books, C Books, FAQ, Forum Search)
    Code painter latest version on sourceforge DOWNLOAD NOW!
    Download FSB Data Integrity Tester.
    Siavosh K C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linking problems in Visual Studio
    By h3ro in forum C++ Programming
    Replies: 5
    Last Post: 03-04-2008, 02:39 PM
  2. VC++ a POS
    By Welder in forum Windows Programming
    Replies: 40
    Last Post: 11-07-2007, 03:07 PM
  3. Variables already defined while linking.
    By xconspirisist in forum C++ Programming
    Replies: 2
    Last Post: 06-10-2005, 05:20 AM
  4. DLL compiling question
    By Noose in forum Windows Programming
    Replies: 2
    Last Post: 12-16-2004, 07:16 AM
  5. Header files
    By borland_man in forum C++ Programming
    Replies: 14
    Last Post: 02-22-2002, 04:30 AM