?
Solved

Implicit conversion problem

Posted on 1997-12-30
11
Medium Priority
?
973 Views
Last Modified: 2012-08-13
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?)
0
Comment
Question by:Rumil
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 2
11 Comments
 
LVL 5

Accepted Solution

by:
yonat earned 400 total points
ID: 1177288
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

http://www.metabyte.com/~fbp/stl/contrib/bstring.h
or (a differnt implementation)
http://www.metabyte.com/~fbp/stl/contrib/string.zip

Or you can use the rope class, developed by SGI. You can read about the differences between rope and string at
http://www.sgi.com/Technology/STL/string_discussion.html
http://www.sgi.com/Technology/STL/Rope.html
Using rope is especially important if your application is multi-threaded.

You can get rope with the rest of the STL portable version at
http://www.metabyte.com/~fbp/stl/
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177289
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?
0
 
LVL 5

Expert Comment

by:yonat
ID: 1177290
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.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 22

Expert Comment

by:nietod
ID: 1177291
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.
0
 

Author Comment

by:Rumil
ID: 1177292
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?
0
 
LVL 5

Expert Comment

by:yonat
ID: 1177293
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.

0
 
LVL 22

Expert Comment

by:nietod
ID: 1177294
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.
0
 
LVL 5

Expert Comment

by:yonat
ID: 1177295
nietod is right. You should reject my answer, and ask him to submit one.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177296
Does removing that stuff make the conversion work?
0
 

Author Comment

by:Rumil
ID: 1177297
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.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177298
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.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question