all groups > visual c libraries > september 2005 >
You're in the

visual c libraries

group:

CStringT methods


CStringT methods Norman Diamond
9/13/2005 12:00:00 AM
visual c libraries:
When MSDN says that a CStringT method takes an argument of type XCHAR (i.e.
Unicode instance takes Unicode argument and ANSI instance takes ANSI
argument), is there an overloaded method that takes an argument of type
YCHAR (i.e. Unicode instance accepts ANSI argument and ANSI instance accepts
Unicode argument)?

By reading MSDN's text the answer seems to be no. No such overloads are
documented.

By reading MSDN's examples the answer seems to be yes. Otherwise MSDN's
examples would not even be compilable.

Since MSDN's text even warns readers about the pitfalls of calling
undocumented methods, I do not wish to experiment to find out what happens
to work in the past two years' worth of versions. I wish to know what
answer we are supposed to get from the documentation.

Example pages for CStringT::ReverseFind in VC++2003:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/vclrfCStringTReverseFind.asp
and in VC++2005 beta:
http://msdn2.microsoft.com/en-us/library/d269k6dz(en-US,VS.80).aspx
Re: CStringT methods Jochen Kalmbach [MVP]
9/13/2005 11:17:05 AM
Hi Norman!
[quoted text, click to view]

???
See: CStringT::CStringT
http://msdn.microsoft.com/library/en-us/vclib/html/vclrfCStringTCStringT.asp

There is an constructor for const XCHAR* and const YCHAR*...

--
Greetings
Jochen

My blog about Win32 and .NET
Re: CStringT methods Norman Diamond
9/14/2005 12:00:00 AM
[quoted text, click to view]

OK a constructor is a method so you are right that some such overloads are
documented. There are constructors accepting the opposite kind of arguments
exactly as you say.

Since my original wording was almost as unclear as MSDN, I fix it here:

When MSDN says that a CStringT method (other than constructor) takes an
argument of type XCHAR (i.e. Unicode instance takes Unicode argument and
ANSI instance takes ANSI argument), is there an overloaded method that takes
an argument of type YCHAR (i.e. Unicode instance accepts ANSI argument and
ANSI instance accepts Unicode argument)?

By reading MSDN's text the answer seems to be no. No such overloads are
documented (except for constructors).

By reading MSDN's examples the answer seems to be yes. Otherwise MSDN's
examples (calling methods other than constructors) would not even be
compilable.

Since MSDN's text even warns readers about the pitfalls of calling
undocumented methods, I do not wish to experiment to find out what happens
to work in the past two years' worth of versions. I wish to know what
answer we are supposed to get from the documentation.

Example pages for CStringT::ReverseFind in VC++2003:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/vclrfCStringTReverseFind.asp
and in VC++2005 beta:
http://msdn2.microsoft.com/en-us/library/d269k6dz(en-US,VS.80).aspx
Please observe that this method is not a constructor.
Re: CStringT methods Jochen Kalmbach [MVP]
9/14/2005 12:00:00 AM
Hi Norman!

[quoted text, click to view]

Can you please point me to an MSDN example?

Or what was the question?
The documentation for "CStringT::ReverseFind" only has a XCHAR parameter...

So where is it used with YCHAR?

--
Greetings
Jochen

My blog about Win32 and .NET
Re: CStringT methods Norman Diamond
9/15/2005 12:00:00 AM
[quoted text, click to view]

Yes. For the third time in fact.
Example pages for CStringT::ReverseFind in VC++2003:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/vclrfCStringTReverseFind.asp
and in VC++2005 beta:
http://msdn2.microsoft.com/en-us/library/d269k6dz(en-US,VS.80).aspx

[quoted text, click to view]

When MSDN says that a CStringT method (other than constructor) takes an
argument of type XCHAR (i.e. Unicode instance takes Unicode argument and
ANSI instance takes ANSI argument), is there an overloaded method that takes
an argument of type YCHAR (i.e. Unicode instance accepts ANSI argument and
ANSI instance accepts Unicode argument)?

[quoted text, click to view]

Right, that's what I said:
* By reading MSDN's text the answer seems to be no. No such overloads are
* documented (except for constructors).

[quoted text, click to view]

Here:
@ //typedef CStringT< TCHAR, StrTraitATL< TCHAR > > CAtlString;
@
@ CAtlString s( "abcabc" );
@ _ASSERT( s.ReverseFind( 'b' ) == 4 );

In a Unicode environment, the argument to ReverseFind is a YCHAR not an
XCHAR. According to the text of this MSDN page, the example should not even
be compilable.
Re: CStringT methods Norman Diamond
9/15/2005 12:00:00 AM
[quoted text, click to view]

I think that mostly we weren't but I will have to adjust my first claim and
add a second example. I was wrong to say that the first example was not
compilable. The second example really will not be compilable.

My first example was ReverseFind as stated.

[quoted text, click to view]

You are right, wchar_t is still an integral type (though it is not a signed
integer type and not an unsigned integer type), so there is an
integral-conversion from char to wchar_t.

So for my first citation of an example, I was wrong to say that it is not
compilable. My question is still meaningful though. Here I will create an
example which is different from MSDN's example:
CAtlString s( "$B$"$$$&$"$$$&(B" );
_ASSERT( s.ReverseFind( '$B$$(B' ) == 4 );
This is compilable for the same reason as MSDN's example is compilable, but
the result is doubtful. There is a constructor for s that takes a parameter
of type YCHAR*, so the ANSI string "$B$"$$$&$"$$$&(B" will be converted to
Unicode string L"$B$"$$$&$"$$$&(B" and stored as the initial value of s. In the
argument to ReverseFind, the character literal '$B$$(B' has type int (because it
consists of more than one c-char) and it undergoes an integral conversion to
wchar_t, but I doubt that an integral conversion produces the same value as
L'$B$$(B'.

[quoted text, click to view]

OK, I think this is evidence that MSDN's text is correct, for CStringT
methods other than constructors, where methods are defined as taking
parameters of type XCHAR or XCHAR* but not as taking parameters of type
YCHAR or YCHAR*, there truly aren't overrides taking parameters of type
YCHAR or YCHAR*. This seems to be an answer to my original question.

But here's another example. Example pages for CStringT::Find in VC++2003:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/vclrfCStringTFind.asp
and in VC++2005 beta:
http://msdn2.microsoft.com/en-us/library/hz2099kw(en-US,VS.80).aspx

Notice MSDN's example code:
@ //typedef CStringT< TCHAR, StrTraitATL< TCHAR > > CAtlString;
@
@ CAtlString s( "abcdef" );
@ _ASSERT( s.Find( 'c' ) == 2 );
@ _ASSERT( s.Find( "de" ) == 3 );

Since "de" has type char*, it has no automatic conversion to type wchar_t*,
and this should not be compilable.

At the time of asking my original question, I considered it unclear whether
to rely on MSDN's text or MSDN's examples. If we rely on this example then
this method has an override taking a parameter of type YCHAR*. Now it seems
we should consider this example to be wrong.

(By the way I have a feeling of deja vue about this example. Maybe this
MSDN bug was reported two years ago but MSDN bugs need more than two years
before they get corrected?)
Re: CStringT methods Jochen Kalmbach [MVP]
9/15/2005 8:41:19 AM
Hi Norman!

[quoted text, click to view]

Maybe we are talking about different things...

[quoted text, click to view]

Ok, now I understand a little bit more...

A "char-literal" ('b') can be used with char and wchar_t, therefor it
will compile with and without UNICODE.
There is also an integral-conversion from char to wchar_t.

If you modify the example to:
<code>
CString s;
char a = 'a';
wchar_t w = 'w';
s.ReverseFind('a');
s.ReverseFind(a);
s.ReverseFind(w); // => Will generate C4244 (possibleloss of data)
</code>

And compile without UNICODE, then it will generate C4244...

--
Greetings
Jochen

My blog about Win32 and .NET
Re: CStringT methods Jochen Kalmbach [MVP]
9/15/2005 10:56:30 AM
Hi Norman!

[quoted text, click to view]

This is a completely different example and has mainly to do with the
compiler interpreting the source files!!!
You need to set the appropriate codepage, so the compiler is able to
translate the "ANSI"-chars in your source file into the correct codepage.

The value of "$B$"$$$&$"$$$&(B" is *not* converted to uncode by the
compiler!!! It is converted to MBCS (with the codepage you have choosen)!
If you want unicode, please use L!

The character '$B$$(B' is also converted using the compilers-codepage!
And it is not suggested to use characters > 126 in your source-code.
This mostly leads to problems...

Please store your string either in resources or in some other (unicode)
files!

[quoted text, click to view]

Yes. This example is simply wrong. Correct should be:
_ASSERT( s.Find( TEXT("de") ) == 3 );

[quoted text, click to view]

Maybe...

--
Greetings
Jochen

My blog about Win32 and .NET
Re: CStringT methods Norman Diamond
9/16/2005 12:00:00 AM
[quoted text, click to view]

Yes, I said I had to adjust my first example. My second example is more
important now. Please look at it again.

[quoted text, click to view]

Huh???????

Windows XP SP2 defaults to the correct code page during installation (932 in
this country). Visual Studio 6, 2003, and 2005 beta obey the existing
setting of the code page (or at least the versions sold in this country do).
I do not have to set anything.

When I install a US version from MSDN, I do have to set Windows regional
options and some Visual Studio options in order to make them resemble
ordinary versions. They work.

However, that is for ANSI characters in my source file. ANSI literals are
not Unicode literals, and this is not because of regional options or
compiler settings, it is because '' literals are not L'' literals.

[quoted text, click to view]

Bingo. Now you know why I said that, even though you are right about
integral conversions occuring, I think that integral conversions will
produce incorrect results.

[quoted text, click to view]

It is not converted, it is already MBCS in the first place, in the codepage
that Microsoft chose when Microsoft sold their products in this country.

[quoted text, click to view]

Bingo. Now you really know why I said that, even though you are right about
integral conversions, it is highly doubtful that MSDN's examples will
produce correct results. And that's only for examples which compile
(because of integral conversions), it still doesn't do a thing for examples
which don't compile.

[quoted text, click to view]

It is not converted at all. The compiler obeys Windows' code page.

[quoted text, click to view]

Oh really. Do you use German characters in character literals and string
literals in your source programs? Can you figure out why some programmers
who are Japanese or live in Japan or target the Japanese market might use
Japanese characters in their source programs? Sure it's better to use
message catalogs and not use any character literals or string literals at
all in source programs. But C and C++ languages do have character literals
and string literals, and programmers use them. And guess what, they don't
lead to problems. Problems only arise when someone tries to compile them
with foreign regional options set, or execute them with foreign regional
options set.

[quoted text, click to view]

Why? There is no integral conversion from char* (the type of string literal
"de") to wchar_t* (the type of the XCHAR* parameter to CStringT::Find).
This example is simply wrong because it cannot even compile. You proved
that I was wrong in my first choice of example because integral conversions
yielded compilation with doubtful result, but my second choice of example
correctly proves my complaint. If there is no override for CStringT::Find
to take a parameter of type YCHAR* then this MSDN example does not even
compile.
Re: CStringT methods Norman Diamond
9/16/2005 12:00:00 AM
[quoted text, click to view]

OK. Most Japanese programmers and I think probably most German programmers
aren't as diligent as you. Also the C and C++ language standards do not try
to impose such diligence -- if they did, then character literals and string
literals would not exist.

And MSDN doesn't try to impose such diligence, as we see in some examples
^u^

And I think we can guess another famous country where most programmers put
some strings in their programs instead of in resource files ^u^

[quoted text, click to view]

I meant this example in MSDN is wrong. Now I see that you said the same
thing, so I should not have repeated my statement. For some reason I
misinterpreted your statement "Correct should be...", but now I can't
remember what I was thinking. Sorry.

Anyway my question has been answered, most of the methods do not have YCHAR
versions, the text in these pages is more accurate than average, and the
examples in these pages are less accurate than average. Thank you.
Re: CStringT methods Jochen Kalmbach [MVP]
9/16/2005 8:18:11 AM
Hi Norman!

[quoted text, click to view]

No. Beacause of the problems with source-code-codepage-conversion...
All texts are stored in resource files...

[quoted text, click to view]

No.

[quoted text, click to view]

??? Please cut-n-past the example, add the "TEXT" and it works...

[quoted text, click to view]

Yes. As I said. Just add the TEXT-macro and it will compile...

--
Greetings
Jochen

My blog about Win32 and .NET
AddThis Social Bookmark Button