Implicit conversion problem

I declare a function which takes a CString, and then pass a JString to it.  A typecast is necessary, so I create JString::operator CString () const, which builds and returns a CString that copies the JString.

Implicit conversion is done, and my function runs correctly, but on exiting, a memory library de-allocation error results.  If I _explicitly_ convert the JString parameter to a CString with a simple (CString) typecast, there's no problem!  Why does MSVC 1.52 produce different object code for these possibilities, and how can I fix the implicit conversion to work correctly?

(Or better still, is there a simple C++ string class available that is more efficient than the MFC CString class, and can return references to strings rather than creating gratuitous copies whenever you return string values, like Java's string class?)
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Why not use the standard string class (std::string)? It is a reference counted string, with many convinient operations. I don't know about VC 1.52, but VC5 has it (#include <string>). You can get free portable implementations from
or (a differnt implementation)

Or you can use the rope class, developed by SGI. You can read about the differences between rope and string at
Using rope is especially important if your application is multi-threaded.

You can get rope with the rest of the STL portable version at

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
I beleive that MFC's string class is well written and it works well with MFC.  (MFC procedures may take it as a parameters, so using a different type of string is inconvenient and may require lots of conversions, and since conversions are the problem...)

In any case, regardless of the string used, this problem should not happen.

The common problems I've seen in this area are: procedures that allocate memory that does not get disposed or procedures that return pointers to local variables or return structures that use pointers to local variables. Can you post the code of your conversion and any other necessary code?
The advantage of using the standard string class is that it is, well, standard. The advantage of using CString is that MFC uses it. So if you want your code to be portable, you should use the standard string. If your code is closely bound to MFC, use CString.
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

I was under the impression (maybe mistakenly as I re-read the question) that Rumil is using MFC, and thus felt that MFC's strings make sense.  In any case, the problem may not be in the string he chooses, but in the code that uses the string.
RumilAuthor Commented:
Problem: Where do I find good documentation for the standard string class?  It would take me a very long time to determine whether the class is adequate for my needs by reading the source code.  Even MFC is more legible.

MFC's CStrings are inadequate for my needs because it's not safe under Visual C++ 1.52 to return a reference to a CString.  Whenever I have a chain of functions that each pass a CString back to the last one, my program must return the CString "by value," wasting a lot of time copying memory.  Also, I've had some memory-allocation problems; code like <string = "Longer string", string = "Short"> will always leave the extra bytes allocated, and I know no way to free the space without deleting the whole string.

My code uses MFC, but not heavily enough to require frequent conversion if I thoroughly replace the CString class with JString in my own code.  However, I'm trying to replace CStrings with JStrings in just a few places at a time.  This strategy makes it easier to track down strange memory allocation errors like this one.

Here's the pertinent code:
void AFunction () {
  JString word = "Arbitrary";
  if (Find (word2) != NotFound)...

int Find (CString s)    {  return Doc->Find (s);  }

int CMyDoc::Find (const CString& s) const
  {   ...  }

func CString JString::operator CString () const
  CString retValue;
  for (int loop1 = 0;  loop1 < MSize;  loop1++)
    retValue += MData [loop1];
  return retValue;

This code doesn't work.  But if I rewrite the first line as:
if (Find ((CString) word2) != NotFound)...
there are no problems!

I'm working around this specific problem simply by replacing the operator= with a ConvertToCString function, to force explicit conversion.  But I want to know what's going on to make sure I don't run into other, similar problems as I replace the CString class with my JString class.  Is it indeed just a bizarre Microsoft bug?
Hmm, doesn't sound like the standard string can solve your problems - your conversion operator is not being called implicitly. If this is a compiler bug, it is specific to 1.52 - I haven't seen it in 4.x and 5.0.

I might see your problem, or just a typo.

the line

func CString JString::operator CString () const

should be just

JString::operator CString () const

you do not declare a return value ("CString") for a conversion operator and I have no idea what the "func" bit was.
nietod is right. You should reject my answer, and ask him to submit one.
Does removing that stuff make the conversion work?
RumilAuthor Commented:
I've defined "func" to mean "inline" in my header files, and nothing at all in my source files, allowing me to conveniently move functions in and out of headers in a multi-module program as their complexity changes.  Nothing there.

Unfortunately, removing the "CString" return type didn't change anything either.  The problem is indeed compiler-related; MSVC produces different object code for the function-call depending on whether the typecast is done explicitly or implicitly.  (And yes, I tried deleting the conversion function long ago, just to make sure there were no other implicit conversions available.)

Under the assumption that this is just an obscure MSVC bug, I've replaced my operator CString function with a ConvertToCString function.  I've converted many instances of CStrings in my library to JStrings and CStringImages and haven't discovered any memory leaks yet.  I'm still nervous, though.
What is the difference in the code in the two cases?  That may reveal something.

Also I had missed one of your comments up there mentions a couple  of interesting things.  

You talk about returning strings as references to eliminate copying time.  As you might know, but in case you don't, that cannot be done unless the string is passed to the procedure in some way.  i.e. a conversion procedure cannot create a new (local) string and return a reference to it.  That will result in  problems.  The STL's string class, and I believe (or I would hope) the MFC string class uses reference counted string buffers.  This means that passing/returning strings by value does not involve copying the string and is very fast and efficient.  There is no need to pass/return strings by reference except where you actually need the reference.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.