Reputation: 3951
I have a .h file which I was intending to use only for storing all the information string that will be displayed in my program. In my info.h:
#ifndef __INFO_H
#define __INFO_H
char *info_msg = "This is version 1.0 of NMS.";
//all other strings used by view.c and controller.c
#endif
Then in my view.h I have as follows:
//view.h
#ifndef __VIEW_H
#define __VIEW_H
#include "info.h"
//other stuff like method declaration etc.
#endif
My controller.h is using view.h:
//controller.h
#ifndef __CONTROLLER_H
#define __CONTROLLER_H
#include "view.h"
#include "model.h"
//other stuff line method declaration etc.
#endif
main.c:
#include "controller.h"
int main()
{
//stuff
}
view.c:
#include "view.h"
char esc,up,down,right,left;
void change_character_setting(char pesc, char pup, char pdown, char pright, char pleft)
{
esc = pesc;
up = pup;
down = pdown;
right = pright;
left = pleft;
}
void print_warning()
{
printf("%s \n",info_msg);
}
When I attempt to create the executable the linker complains:
/tmp/ccqylylw.o:(.data+0x0): multiple definition of `info_msg'
/tmp/cc6lIYhS.o:(.data+0x0): first defined here
I am not sure why it would see two definitions since I am using the protection block. I tried to google here but nothing specific showed up. Can someone explain how it is seeing multiple definitions? How do I achieve something as simple in Java to use one single file for all text manipulation in C?
Upvotes: 4
Views: 2231
Reputation: 66254
You're compiling a global variable called info_msg
into each source file that includes info.h
either directly or pulled in from some other header. At link-time, the linker finds all these info_msg
identifiers (one in each object file compiled) and doesn't know which one to use.
Change you're header to be:
#ifndef PROJ_INFO_H
#define PROJ_INFO_H
extern const char *info_msg; // defined in info.cpp
#endif
And assuming you have an info.cpp
(if not you can place this in any .cpp file, but that one would be the most natural location to maintain it):
// info.cpp
#include "info.h"
const char *info_msg = "This is version 1.0 of NMS.";
Note: Be careful when declaring preprocessor symbols and identifiers as to your placement of underscores. According to the C99 standard:
C99 §7.1.3/1
- All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
- All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
Upvotes: 5