10 Jul, 2010, Mudder wrote in the 1st comment:
Votes: 0
It's been awhile since I've done active work and I'm slightly rusty getting back in. I'm using Linux Mint KDE 9 Isadora, I downloaded g++ and g++-4.4 and I'm using netbeans with the C++ plugin.

I'm not exactly what is causing this error.


act_comm.c: In function void do_pmote(CHAR_DATA*, const char*):
act_comm.c:853: error: invalid conversion from const char* to char*


This is line 853.

if ( ( letter = strstr( argument, vch->name ) ) == NULL )


This is the whole function.

void do_pmote( CHAR_DATA *ch, const char *argument )
{
CHAR_DATA *vch = NULL;
char *letter = NULL;
char *name = NULL;
char last[MAX_INPUT_LENGTH] = "\0\0\0\0\0\0\0";
char temp[MAX_STRING_LENGTH] = "\0\0\0\0\0\0\0";
size_t matches = 0;

if ( !IS_NPC( ch ) && IS_SET( ch->comm, COMM_NOEMOTE ) )
{
ch_printf( ch, "You can't show your emotions.\r\n" );
return;
}

if ( argument[0] == '\0' )
{
ch_printf( ch, "Emote what?\r\n" );
return;
}

act( "$n $t", ch, argument, NULL, TO_CHAR );

for ( vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room )
{
if ( vch->desc == NULL || vch == ch )
continue;

if ( ( letter = strstr( argument, vch->name ) ) == NULL )
{
MOBtrigger = false;
act( "$N $t", vch, argument, ch, TO_CHAR );
MOBtrigger = true;
continue;
}

strcpy( temp, argument );
temp[strlen( argument ) - strlen( letter )] = '\0';
last[0] = '\0';
name = vch->name;

for ( ; *letter != '\0'; letter++ )
{
if ( *letter == '\'' && matches == strlen( vch->name ) )
{
strcat( temp, "r" );
continue;
}

if ( *letter == 's' && matches == strlen( vch->name ) )
{
matches = 0;
continue;
}

if ( matches == strlen( vch->name ) )
{
matches = 0;
}

if ( *letter == *name )
{
matches++;
name++;
if ( matches == strlen( vch->name ) )
{
strcat( temp, "you" );
last[0] = '\0';
name = vch->name;
continue;
}
strncat( last, letter, 1 );
continue;
}

matches = 0;
strcat( temp, last );
strncat( temp, letter, 1 );
last[0] = '\0';
name = vch->name;
}
MOBtrigger = false;
act( "$N $t", vch, temp, ch, TO_CHAR );
MOBtrigger = true;
}

return;
}
10 Jul, 2010, Runter wrote in the 2nd comment:
Votes: 0
strstr() expects a char * and you're passing a const char * as the first argument to it.
11 Jul, 2010, JohnnyStarr wrote in the 3rd comment:
Votes: 0
In this scope argument is type const char* instead of char* as Runter pointed out.
It sounds like this project is just in C? C++ has an overloaded function for strstr(char * str1, const char * str2) as it's parameter list.

Not sure where you're at as far as upgrading to g++, but it might be worth looking into.
If thats not an option you will need to take a different approach.
11 Jul, 2010, Mudder wrote in the 4th comment:
Votes: 0
I'm not sure. I never had this error with cygwin, but I compile this project with g++
11 Jul, 2010, Tyche wrote in the 5th comment:
Votes: 0
Mudder said:
I'm not sure. I never had this error with cygwin, but I compile this project with g++


Different compiler versions.
The latest cygwin g++ is 4.3.4 and produces a warning that the conversion from const char * to char * will be deprecated.
I think g++ 4.4.x versions flag it as an error now.
The latest VisualC++ compiler also flags it as an error.
11 Jul, 2010, Mudder wrote in the 6th comment:
Votes: 0
Ah, I see. Yes, I am using 4.4 on my linux.
11 Jul, 2010, quixadhal wrote in the 7th comment:
Votes: 0
Anything which is declared as "const" is treated as "constant" or "unchanging" by the compiler. It allows it to do optimizations that assume the value of that variable on entry to the function doesn't change by the time the function exits (however that happens). Since DikuMUD code was written before compilers generally did such things, in many cases things ended up declared "const" but then modified anyways, since the compiler let them get away with it.

In your case, the library function strstr() changes the argument passed to it during processing (It puts NULL bytes into the string as it goes, handing you back substrings). Since your argument is declared const, you can't do that.

To work around it (and you'll need to do a LOT of this in any Dikurivative that hasn't already done it for you), you need to make a temporary copy of your string and do your parsing on it. You can also try to trick the compiler by declaring a "char *" and later setting it to point to the same memory of the "const char *", but if the compiler realizes you did this, you're back to square one.

Good luck!
11 Jul, 2010, Tyche wrote in the 8th comment:
Votes: 0
quixadhal said:
Anything which is declared as "const" is treated as "constant" or "unchanging" by the compiler. It allows it to do optimizations that assume the value of that variable on entry to the function doesn't change by the time the function exits (however that happens). Since DikuMUD code was written before compilers generally did such things, in many cases things ended up declared "const" but then modified anyways, since the compiler let them get away with it.

In your case, the library function strstr() changes the argument passed to it during processing (It puts NULL bytes into the string as it goes, handing you back substrings). Since your argument is declared const, you can't do that.

To work around it (and you'll need to do a LOT of this in any Dikurivative that hasn't already done it for you), you need to make a temporary copy of your string and do your parsing on it. You can also try to trick the compiler by declaring a "char *" and later setting it to point to the same memory of the "const char *", but if the compiler realizes you did this, you're back to square one.

Good luck!


This problem has nothing whatsoever to do with Diku code. They wrote Diku in C and not C++.

strstr() does not modify the string by inserting NUL characters.

In fact it's perfectly valid ANSI C code and declared as:
char * strstr(const char *s1, const char *s2);

However the problem is this declaration doesn't really make sense for obvious reasons.

So in ANSI C++ they declared strstr() as follows:
char * strstr(char *s1, const char *s2);
const char * strstr(const char *s1, const char *s2);

So the variable holding the returned pointer has to be the same type as the first parameter.
11 Jul, 2010, JohnnyStarr wrote in the 9th comment:
Votes: 0
Dude, just use an std::string and move on ;)
#include <iostream>
#include <string.h>
#include <string>

using namespace std;

int main(void)
{
const char* argument = "Hey you guys";
string str;
str.append(argument);
str.replace(str.find("guys"), 5, "Girls!");
cout << str;
}


Hey you Girls!
11 Jul, 2010, Tyche wrote in the 10th comment:
Votes: 0
JohnnyStarr said:
Ahh, that makes sense. I was wondering why it wasn't working with the overloaded method.
So if mudder changes "letter" to be const char* it should be fine yes?


Yes…err maybe. I don't know how vch->name is declared. He might have to cast it to const char*.
12 Jul, 2010, quixadhal wrote in the 11th comment:
Votes: 0
Tyche said:
strstr() does not modify the string by inserting NUL characters.

Sorry, I was thinking of strtok(). My bad.

As to the Diku authors using C instead of C++, whatever. You use C functions out of the standard library, you are writing C code however you may like to delude yourself.
12 Jul, 2010, Tyche wrote in the 12th comment:
Votes: 0
quixadhal said:
As to the Diku authors using C instead of C++, whatever. You use C functions out of the standard library, you are writing C code however you may like to delude yourself.


Nonsense.
12 Jul, 2010, David Haley wrote in the 13th comment:
Votes: 0
The C vs. C++ declaration of strstr thing is a red herring. The point is that DikuMUD was lax with string constness in many places, and often treats string literals as char* when you really shouldn't.
12 Jul, 2010, Tyche wrote in the 14th comment:
Votes: 0
Fact. The do_pmote function was introduced in ROM.
Fact. ROM was written in C, not C++.
Fact. The do_pmote function the poster listed compiles cleanly in modern ANSI-99 standard C.[1]
Fact. The RaM project converted ROM from C to C++
Fact. The RaM project authors are the sole source of the bug the poster posted.
Fact. Neither the Diku team, Merc team nor ROM team are responsible for this bug.
Fact. I provided the poster with a fix.

[1] Proof:

Compile of pmote function from ROM 2.4B6
$ cat rompmote.c
#include <string.h>
#include <time.h>
#include <stdio.h>
#include "merc.h"

void do_pmote( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *vch;
char *letter,*name;
char last[MAX_INPUT_LENGTH], temp[MAX_STRING_LENGTH];
int matches = 0;

if ( !IS_NPC(ch) && IS_SET(ch->comm, COMM_NOEMOTE) )
{
send_to_char( "You can't show your emotions.\n\r", ch );
return;
}

if ( argument[0] == '\0' )
{
send_to_char( "Emote what?\n\r", ch );
return;
}

act( "$n $t", ch, argument, NULL, TO_CHAR );

for (vch = ch->in_room->people; vch != NULL; vch = vch->next_in_room)
{
if (vch->desc == NULL || vch == ch)
continue;

if ((letter = strstr(argument,vch->name)) == NULL)
{
act("$N $t",vch,argument,ch,TO_CHAR);
continue;
}

strcpy(temp,argument);
temp[strlen(argument) - strlen(letter)] = '\0';
last[0] = '\0';
name = vch->name;

for (; *letter != '\0'; letter++)
{
if (*letter == '\'' && matches == strlen(vch->name))
{
strcat(temp,"r");
continue;
}

if (*letter == 's' && matches == strlen(vch->name))
{
matches = 0;
continue;
}

if (matches == strlen(vch->name))
{
matches = 0;
}

if (*letter == *name)
{
matches++;
name++;
if (matches == strlen(vch->name))
{
strcat(temp,"you");
last[0] = '\0';
name = vch->name;
continue;
}
strncat(last,letter,1);
continue;
}

matches = 0;
strcat(temp,last);
strncat(temp,letter,1);
last[0] = '\0';
name = vch->name;
}

act("$N $t",vch,temp,ch,TO_CHAR);
}

return;
}



jlambert@atlas ~
$ gcc -Wall -ansi -std=c99 -c rompmote.c


As you can see not only is ROM's pmote function 100% valid modern ANSI-C99, the merc.h header is as well.

Q.E.D.
12 Jul, 2010, quixadhal wrote in the 15th comment:
Votes: 0
Fact: I was trying to explain *WHY* the const char * issue would likely appear again, not just hand-wave a fix at the OP.
Fact: I didn't see any mention of RaM until Tyche mentioned it.
Observation: Tyche has a rather painful stick lodged in a place that makes sitting down a mite uncomfortable.

I had already explained that I misread strstr() as strtok(), and I maintain that if you're mucking about with string functions from libc, you are indeed using C, even if you're ALSO using C++. Anything else you feel like bitching about today?
12 Jul, 2010, ralgith wrote in the 16th comment:
Votes: 0
Can everyone just untwist their panties already? :P
12 Jul, 2010, Tyche wrote in the 17th comment:
Votes: 0
David Haley said:
The C vs. C++ declaration of strstr thing is a red herring. The point is that DikuMUD was lax with string constness in many places, and often treats string literals as char* when you really shouldn't.


http://www.nizkor.org/features/fallacies...
Quote
Also Known as: Smoke Screen, Wild Goose Chase.
Description of Red Herring

A Red Herring is a fallacy in which an irrelevant topic is presented in order to divert attention from the original issue. The basic idea is to "win" an argument by leading attention away from the argument and to another topic. This sort of "reasoning" has the following form:

1. Topic A is under discussion.
2. Topic B is introduced under the guise of being relevant to topic A (when topic B is actually not relevant to topic A).
3. Topic A is abandoned.

This sort of "reasoning" is fallacious because merely changing the topic of discussion hardly counts as an argument against a claim.


1. Topic A is the poster's problem, his code being flagged with an error while using strstr().
2. Topic B was introduced by quixadhal, "Since DikuMUD code was written before compilers generally did such things, in many cases things ended up declared "const" but then modified anyways, since the compiler let them get away with it."

As I have illustrated, the laxity of the DikuMud and derivative coders have absolutely nothing to do with the problem the poster posted. As I have also shown, the problem is in fact entirely due to the differences between C and C++.

3. To all appearances, Mr Haley would like to abandon discussion of the poster's problem and the solution in order to discuss Topic B. He even takes it one step further by boldly declaring that actual discussion of poster's problem and solution to be a "red herring".

I think he's either ignorant or a troll.
But in order to avoid further arguments I'd recommend the poster implement Mr. Haley's solution.
12 Jul, 2010, Tyche wrote in the 18th comment:
Votes: 0
quixadhal said:
Fact: I was trying to explain *WHY* the const char * issue would likely appear again, not just hand-wave a fix at the OP.
Fact: I didn't see any mention of RaM until Tyche mentioned it.
Observation: Tyche has a rather painful stick lodged in a place that makes sitting down a mite uncomfortable.

I had already explained that I misread strstr() as strtok(), and I maintain that if you're mucking about with string functions from libc, you are indeed using C, even if you're ALSO using C++. Anything else you feel like bitching about today?


This problem is clearly caused by "laxity" in understanding the differences between C and C++ . The poster should be prepared as these issues will likely appear again.
No I really don't think it all productive in assigning blame or bashing the previous authors (i.e. Diku, Merc, ROM) for problems introduced by RaM.

YMMV
12 Jul, 2010, Tyche wrote in the 19th comment:
Votes: 0
ralgith said:
Can everyone just untwist their panties already? :P


Spear chucker.
12 Jul, 2010, David Haley wrote in the 20th comment:
Votes: 0
Tyche said:
David Haley said:
The C vs. C++ declaration of strstr thing is a red herring. The point is that DikuMUD was lax with string constness in many places, and often treats string literals as char* when you really shouldn't.


http://www.nizkor.org/features/fallacies...
Quote
Also Known as: Smoke Screen, Wild Goose Chase.
Description of Red Herring

A Red Herring is a fallacy in which an irrelevant topic is presented in order to divert attention from the original issue. The basic idea is to "win" an argument by leading attention away from the argument and to another topic. This sort of "reasoning" has the following form:

1. Topic A is under discussion.
2. Topic B is introduced under the guise of being relevant to topic A (when topic B is actually not relevant to topic A).
3. Topic A is abandoned.

This sort of "reasoning" is fallacious because merely changing the topic of discussion hardly counts as an argument against a claim.


1. Topic A is the poster's problem, his code being flagged with an error while using strstr().
2. Topic B was introduced by quixadhal, "Since DikuMUD code was written before compilers generally did such things, in many cases things ended up declared "const" but then modified anyways, since the compiler let them get away with it."

As I have illustrated, the laxity of the DikuMud and derivative coders have absolutely nothing to do with the problem the poster posted. As I have also shown, the problem is in fact entirely due to the differences between C and C++.

3. To all appearances, Mr Haley would like to abandon discussion of the poster's problem and the solution in order to discuss Topic B. He even takes it one step further by boldly declaring that actual discussion of poster's problem and solution to be a "red herring".

I think he's either ignorant or a troll.
But in order to avoid further arguments I'd recommend the poster implement Mr. Haley's solution.

… … …what? :thinking:

Oh, by the way, Tyche...
0.0/21