15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


CString - wrong constructor called during param passing

Dave Blatt/Newcastle/Computer Systems Australia/AU -- Dave_Blatt@compsys.com.au
Sunday, June 16, 1996

Environment Win95, MSCVC4.1

I am having problems calling routines with parameter(s) declared as
  const CString&
when the actual calling parameter is a quoted string (eg "abc").
It is calling the wrong constructor... obvious when stepping through
via debug trace.  For example...

void MyDlg::OnXXX() {
 CString val;
 ...etc...  val = "whatever";
 m_vars->Insert("dseldpr","desc",val); //<<<====failing call
 ...etc...
}

 is calling routine m_vars->Insert() which is declared as

BOOL ImportVars::Insert(
  const CString& field, //<<<===should construct a CString("dseldpr")
  const CString& var, //<<<===should construct a CString("desc")
  const CString& value);


During calling, I can trace through the parameter construction and
it calls the  C:\msdev\Mfc\src\Strex.cpp   routine:
 CString::CString(TCHAR ch, int nLength) {...}
instead of the (expected)  C:\msdev\Mfc\src\Strcore.cpp routine:
 CString::CString(LPCTSTR lpsz) {...}

 !!!!?????!!!!!

Note that in almost all other similar function calls in the code,
the correct constructor *is* called.  This odd behaviour (calling the
TCHAR constructor) appears to happen in a few calls only, but is
quite repeatable and consistent when it does.  I'm trying to port an
application which was working fine in MSVC1.5 across to MSVC4.1.
At first I thought it was only happening in one class, and I "fixed"
it by changing all the const CString& 's  to LPCTSTR's. Of course,
there's a bit of hack work required in this, because
once you arrive in the procedure with a primitive LPCTSTR instead
of a CString, you probably are going to need to construct a local
CString anyway to do the work if any of the CString member functions
are being used.

I looked in the online help, and the suggestion is to
use LPCTSTR for formal parameters for "most flexibility", but
nowhere does it say that "const CString&" params will fail, and
indeed they nearly always work.  Changing the whole app to LPCTSTR's
would also be a great pain as there are hundreds of these, and many
of the routines use CString members liberally, making lots of flow
on hack work necessary.

It is not consistent, and I've had a bit of trouble trying to cut the
application down to a standalone demo.  All attempts so far have
given test applications which don't fail like this.  I am sure
I can start with the full (failing) application and slowly cut it down
to a smallish subset which exhibits this failure, but before I spend
(more) hours and hours doing that, I thought perhaps this is a known
problem with maybe even a workaround (project settings?? whatever??).

Any info/ideas welcome!

-- Dave Blatt





Paulo Soares -- psoares@ip.pt
Monday, June 17, 1996

[Mini-digest: 3 responses]

On Monday, June 17, 1996 0:00 AM, Dave Blatt/Newcastle/Computer Systems Australia/AU[SMTP:Dave_Blatt@compsys.com.au] wrote:
>Environment Win95, MSCVC4.1
>
>I am having problems calling routines with parameter(s) declared as
>  const CString&
>when the actual calling parameter is a quoted string (eg "abc").
>It is calling the wrong constructor... obvious when stepping through
>via debug trace.  For example...
>
>void MyDlg::OnXXX() {
> CString val;
> ...etc...  val = "whatever";
> m_vars->Insert("dseldpr","desc",val); //<<<====failing call
> ...etc...
>}
>
> is calling routine m_vars->Insert() which is declared as
>
>BOOL ImportVars::Insert(
>  const CString& field, //<<<===should construct a CString("dseldpr")
>  const CString& var, //<<<===should construct a CString("desc")
>  const CString& value);
>
>
>During calling, I can trace through the parameter construction and
>it calls the  C:\msdev\Mfc\src\Strex.cpp   routine:
> CString::CString(TCHAR ch, int nLength) {...}
>instead of the (expected)  C:\msdev\Mfc\src\Strcore.cpp routine:
> CString::CString(LPCTSTR lpsz) {...}
>
> !!!!?????!!!!!
>
>Note that in almost all other similar function calls in the code,
>the correct constructor *is* called.  This odd behaviour (calling the
>TCHAR constructor) appears to happen in a few calls only, but is
>quite repeatable and consistent when it does.  I'm trying to port an
>application which was working fine in MSVC1.5 across to MSVC4.1.
>At first I thought it was only happening in one class, and I "fixed"
>it by changing all the const CString& 's  to LPCTSTR's. Of course,
>there's a bit of hack work required in this, because
>once you arrive in the procedure with a primitive LPCTSTR instead
>of a CString, you probably are going to need to construct a local
>CString anyway to do the work if any of the CString member functions
>are being used.
>
>I looked in the online help, and the suggestion is to
>use LPCTSTR for formal parameters for "most flexibility", but
>nowhere does it say that "const CString&" params will fail, and
>indeed they nearly always work.  Changing the whole app to LPCTSTR's
>would also be a great pain as there are hundreds of these, and many
>of the routines use CString members liberally, making lots of flow
>on hack work necessary.
>
>It is not consistent, and I've had a bit of trouble trying to cut the
>application down to a standalone demo.  All attempts so far have
>given test applications which don't fail like this.  I am sure
>I can start with the full (failing) application and slowly cut it down
>to a smallish subset which exhibits this failure, but before I spend
>(more) hours and hours doing that, I thought perhaps this is a known
>problem with maybe even a workaround (project settings?? whatever??).
>
>Any info/ideas welcome!
>
>-- Dave Blatt
>
>
>
>

I also had a couple of problems similar to this and they always fell in two categories:
- I was linking with the wrong lib
- Doing a full rebuild solved the problem (after this I have never used incremental link and minimal rebuild)

Hope this helps.

Best Regards,
Paulo Soares
psoares@ip.pt
-----From: Mario Contestabile

>void MyDlg::OnXXX() {
> CString val;
>...etc...  val = "whatever";
> m_vars->Insert("dseldpr","desc",val); //<<<====failing call
> ...etc...
>}
>
> is calling routine m_vars->Insert() which is declared as
>
>BOOL ImportVars::Insert(
>  const CString& field, //<<<===should construct a CString("dseldpr")
>  const CString& var, //<<<===should construct a CString("desc")
>  const CString& value);

==========
a(const CString& _p){}
b(const LPCTSTR _p){}

a("test"); // Will call CString::CString(LPCTSTR lpsz){} CTOR
whereas
b("test"); // Calls no CTOR

CString t("test");
a(t);   // Calls no CTOR
b(t);  //  Calls CString::operator LPCTSTR() const {}

Such is the behavior in MSVC 4.1

-----From: Wolfgang Loch 

Hi Dave,

Why, if in almost every situation the correct contructor is called,
don't you use in this case explicitly the CString(LPCTSTR) constructor
like this:
{
 CString val;
 ...etc...  val = "whatever";
 m_vars->Insert( CString("dseldpr"), CString("desc"), val );
 ...etc...
}

-- 
/--------------------------------------------------------------\
| Wolgang Loch, Student of the Technical University of Ilmenau |
|   e-mail: Wolfgang.Loch@rz.TU-Ilmenau.DE                     |
|   www   : http://www.rz.tu-ilmenau.de/~wolo                  |
\--------------------------------------------------------------/



Dave Blatt/Newcastle/Computer Systems Australia/AU -- Dave_Blatt@compsys.com.au
Tuesday, June 18, 1996

Environment:  Win95, VC++/MFC4.1

Responses so far suggest previous report too detailed...
Here's the problem...

****************************************************************
void f(const CString& s){}
f("test"); // should call CString::CString(LPCTSTR lpsz){} ctor
****************************************************************
but occasional instances call
 CString::CString(TCHAR ch, int nLength)
ctor ???!!!
****************************************************************

Hope this is clear,
thanks
  Dave Blatt






| Вернуться в корень Архива |