Smaug compiling using g++

Posted by Robert Powell on Thu 06 Dec 2007 10:16 PM — 16 posts, 68,433 views.

Australia #0
I have a need to make my source compile in g++, i ran it through just to see how many errors there would be and see how much work is involved.

I know others here have done this sort of madness before and was after some suggestions on the best way to approach it.

The reward for me doing this is a totally out of this world prog system thats been written for smaug using C++ methods.
USA #1
What kind of errors are you getting? One of the most common ones is that 'class' is a keyword in C++ so you can't have fields called 'class'. I don't remember the process as being that hard, just a large number of details to take care of.
USA #2
out of this world prog system?? tell us more
USA #3
The best way to approach it is one small chunk at a time. Don't let the volume of errors and warnings get to you.

If your Makefile has extra flags to trigger more warnings than usual, you might want to try disabling some of those at first. It'll make weeding out the real problems a little easier. It might also be helpful to add -Werror so that you only get one file's worth of information at a time. It makes things a bit more manageable that way.

There's also a script that was posted to this forum somewhere that will do the dirty work of making ->class into ->Class so that the compiler will quit complaining about the member name. You'll get the same from a few places that use ->new as a member name.

And of course, we're all curious about this new mudprog code you've mentioned :)
Australia #4
i did a bit of searching for this script, does anyone have an actual link to it, because i cannot find it.
Australia Forum Administrator #5
Something like this should do it:


 perl -pi -e 's/class/Class/g' *.c

Australia #6
Ok, now we go onto the next step of actually fixing the bits of code that G++ has a time dealing with.


g++ -c -g2 -Wall -Wshadow -Wformat-security -Winline -Wpointer-arith -Wcast-align -Wredundant-decls -export-dynamic act_obj.c
act_obj.c: In function ‘void do_rolldie(CHAR_DATA*, char*)’:
act_obj.c:3406: error: invalid conversion from ‘void*’ to ‘bool*’
act_obj.c: In function ‘char* get_chance_verb(OBJ_DATA*)’:
act_obj.c:3489: error: invalid conversion from ‘const char*’ to ‘char*’
gmake: *** [act_obj.o] Error 1
*** Exited with status: 2 ***


and the block of code,


char *get_chance_verb( OBJ_DATA * obj )
{
   return ( obj->action_desc[0] != '\0' ) ? obj->action_desc : "roll$q";
}


From the look of it most of my errors are just like this one, invalid conversions, but i have no idea what it means and even less of an idea on how to fix it. Thanks for your help.
USA #7
The nasty fix is to cast the below to char* before returning it. The proper fix is to change the function's return type to const char* and adjusting code that calls it wherever necessary.

There was a thread on the FUSS forums about why it's such a problem to do the "nasty fix", but unfortunately it was lost during a drive crash. The short version is that the string literal "roll$q" is in the data segment of the program and most operating systems will prevent you from writing to it. But if you treat it as a char*, the compiler will cheerfully let you modify it, which will produce crashes.
Australia #8
Ok, i have gotten to the point where every file compiles all be it with a bunch of warnings about signed and unsigned ints that i will fix later.

My main problem now is when it goes to link everything together is spits out a multitude of errors about multiple definitions.

Most of them seem to do with things that use LINK and UNLINK


ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2289: multiple definition of `first_homebuy'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2337: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2289: multiple definition of `last_homebuy'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2337: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2291: multiple definition of `first_lmsg'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2341: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2293: multiple definition of `last_lmsg'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2341: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2293: multiple definition of `first_home'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2342: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2293: multiple definition of `last_home'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2342: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2293: multiple definition of `first_accessory'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2343: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2294: multiple definition of `last_accessory'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2343: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2294: multiple definition of `DONT_UPPER'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2341: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2294: multiple definition of `area_version'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2341: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':
/home/robert/eldhamud.v5/src/act_info.c:2298: multiple definition of `MOBtrigger'
ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2341: first defined here
ObjectFiles/act_info.o: In function `str_similarity(char const*, char const*)':


I tryed doing this to each of my headers so they only get defined one time, but even that didnt seem to do anything, i just got the same mass of linking errors.


#if !defined(_INC_HOUSE_H_) 
#define _INC_HOUSE_H_
^
codeblock
^
#endif //_INC_HOUSE_H_ 


Thanks in advance for any idead to whats going on here.
USA #9
Let's start with the first error. What exactly is: first_homebuy and what do the two definitions look like? e.g. show those two lines of code.

One thing is that you might need to do the ol' make-clean and remake...
Australia #10
First one,

/home/robert/eldhamud.v5/src/act_info.c:2289: multiple definition of `first_homebuy'


>>> short str_similarity ( const char *astr, const char *bstr )
{
	short matches = 0;

	if ( !astr || !bstr )
		return matches;

	for ( ; *astr; astr++ )
	{
		if ( LOWER ( *astr ) == LOWER ( *bstr ) )
			matches++;

		if ( ++bstr == '\0' )
			return matches;
	}

	return matches;
}


2nd one

ObjectFiles/act_comm.o:/home/robert/eldhamud.v5/src/act_comm.c:2337: first defined here


>>>bool circle_follow( CHAR_DATA * ch, CHAR_DATA * victim )
{
   CHAR_DATA *tmp;

   for( tmp = victim; tmp; tmp = tmp->master )
      if( tmp == ch )
         return TRUE;
   return FALSE;
}


From house.h

HOMEBUY_DATA *first_homebuy;
HOMEBUY_DATA *last_homebuy;

I dont know what more to add, other than it has confused the heck out of me. Oh and i had make cleaned it each time i compiled.
Amended on Tue 11 Dec 2007 12:58 AM by Robert Powell
USA #11
Umm... hrm. That's not making any sense at all. :-)

Is there a place you could put the source files for me to download? If you don't mind I'd like to try compiling them myself...
Australia #12
Not at all, i just emailed it to you at your at-the-haleys.org address.
USA #13
From house.h

HOMEBUY_DATA *first_homebuy;
HOMEBUY_DATA *last_homebuy;


In the .h file those should have "extern" in front, without the quotes. Then somewhere in the source code for the housing system, put the declarations in, without the extern.
Australia #14
Thanks samson, that is exactly what was happening, but could you explain to me why it was happening so i can understand things a bit better.
USA #15
Ah yes, good old extern, I didn't notice those were coming from a .h file.

OK... well, the thing is that whenever the compiler sees something of the form:

VAR_TYPE VAR_NAME;

it creates memory of size sizeof(VAR_TYPE) and all future occurrences of VAR_NAME will refer to that block of memory.

But sometimes you want to let several source files know that a given variable (i.e. named block of memory) exists. You could do something like VAR_TYPE VAR_NAME; in each source file, but that would be incorrect: that would create one block per file. That is the error you were getting, actually: the compiler was telling you that something was happening you didn't want.

The extern keyword tells the compiler not to allocate the memory, but to defer looking up that variable's memory address until the link phase. That way, all of your source files contain references to the variable name, but not the location in code; during link, the linker will go in and fix all those references to point to the right place.

So, you still need somewhere to have VAR_TYPE VAR_NAME in order for the compiler to allocate the memory. But you only want that in one spot: everywhere else where you want to [i]refer[/i] to that variable you need to have the extern keyword in front.

The intuition behind the keyword is that you are declaring that a variable is external with respect to the file being compiled, that is, you are assuring the compiler that the variable has memory out there somewhere and that it should defer looking that up until it has the external object files to link against.