From: Joseph M. Newcomer on
const is a keyword in the C language, and therefore can be used in C programming!

It is not specific to C++.

Recently, I added a bunch of const declarations to a C- based library; we actually
uncovered some errors as a consequence! For example, there was a function that modified
an input string by writing into it, and this would have failed if a literal string was
passed in! (The result, because literal strings are placed in read-only memory, would
have been an access fault; and when I reported this, the response was "Yeah, we had some
tech support calls on that which we now understand")
joe

On Thu, 13 May 2010 23:47:43 -0700 (PDT), Goran <goran.pusic(a)gmail.com> wrote:

>On May 14, 3:04�am, "JCO" <some...(a)somewhere.com> wrote:
>> It really sounds like (for MFC) it's better to completely stay away from
>> LPCTSTR & TCHAR.
>
>Pretty much, yeah. At any rate, whenever you have a CString, and you
>interact with a C API that has C string parameter, you'll either go
>through directly through CString's "C string" conversion operators
>(see operator PCXSTR in CString), or you will be forced to use one of
>"buffer" routines for non-const params.
>
>> Use CString, CString& or similarly with the "const" in front for Read Only.
>
>Yes. It's not "Read only", it's more "input", really. Normally, you
>really rarely want to use plain CString. You want that when you want
>to pass it as an input (by value), and you want to modify it inside,
>e.g. (warning: hugely contrived example):
>
>void f(CString s)
>{
> if (whatever) s = val1; else s = val2;
> someOtherFunc(s);
>}
>
>But that's just the same as:
>
>void f(const CString& s)
>{
> CString local(s)
> if (whatever) local = val1; else local = val2;
> someOtherFunc(s);
>}
>
>(BTW, I bet you that you won't be able to see performance difference
>in an optimized build between the two versions, and it's even possible
>that compiler will compile the two to the exact same code).
>
>As Joe said, using const for "input" parameters has a good
>"documentation" value. I wonder if this will ever become a part of
>typical coding guidelines for C and C++ (it should have, by now, but C
>is an old language, and if it still isn't there for C code, so chances
>of that ever happening are slim).
>
>Goran.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
Under any possible scenario, the code you show has to be incorrect. You may not under any
cirucmstances modify a global variable in that fashion; in fact, the code is incorrect if
the global variable is an int. In the case of the CString, the integrity of the data
value itself can be compromised, and the code would be incorrect at a deep level without
locking. With locking, it is still incorrect at the superficial level. So arguming about
CString or its value is meaningless; if the variable was an LPTSTR the code would still be
wrong.
joe

On Fri, 14 May 2010 14:01:15 -0700 (PDT), "John H." <oldman_fromthec(a)yahoo.com> wrote:

>Goran wrote:
>> On May 14, 3:04�am, "JCO" <some...(a)somewhere.com> wrote:
>> > Use CString, CString& or similarly with the "const" in front for Read Only.
>>
>> Yes. It's not "Read only", it's more "input", really. Normally, you
>> really rarely want to use plain CString. You want that when you want
>> to pass it as an input (by value), and you want to modify it inside,
>
>Although probably a rare case, but in a multithreaded app, the
>difference between CString and CString const & could be important.
>e.g.
>
>// Global resource:
>CString csName("Albert");
>
>// Thread 1:
>...
>DoSomething(csName); // line 1
>...
>
>// Thread 2:
>...
>csName = "Alex"; // line 2
>...
>
>Now consider if DoSomething is defined as
>void DoSomething(CString csFriend)
>{
> ...
> cout << csFriend<< endl; // line 3
>}
>
>Now consider line1 begins execution, and the name "Albert" is copied
>into the csFriend argument. Then control switches to thread 2 and
>line 2 is executed. Then control goes back to thread 1 and line 3 is
>executed. "Albert" will be printed.
>
>If on the other hand DoSomething is defined with reference:
>void DoSomething(CString const & csFriend)
>{
> ...
> cout << csFriend<< endl; // line 3
>}
>
>With the same serious of executions steps, "Alex" would be printed.
>
>Depending on what you are trying to do, either one could be the
>desired behavior.
****
Anyone reading this code would realize that independent of the parameter type or the
copy-on-write semantics of CString, these is nothing right about the above code.
joe
****
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
See below...
On Fri, 14 May 2010 03:13:01 -0400, Hector Santos <sant9442(a)gmail.com> wrote:

>JCO wrote:
>
>> It really sounds like (for MFC) it's better to completely stay away from
>> LPCTSTR & TCHAR.
>> Use CString, CString& or similarly with the "const" in front for Read Only.
>
>
>Yes, if you wish to ignore any performance lost due to the extra
>overhead. But today's computers are fast so who cares? :)
****
No only that, but statistically the time is insignificant in nearly all cases. If this
were happening billions of times in an inner loop, the time might become statistically
significant.
****
>
>But the other thing is issues may rear its ugly head when you are
>passing it across boundaries, like between the exe and dlls.
>
>For example, if you put your functions in a DLL, now they are highly
>dependent on MFC being included in the DLL when it might have to be if
>you are using passing a const string pointer and can work with it with
>out needing the help from CString member functions.
****
I always assume a shared MFC DLL. The DLL runtime issue is one of the ugly secrets of C++
programming that Nobody Talks About, like the weird uncle at a family gathering. But as
soon as you have separate runtimes (static linking) all bets are off, not only for CString
but for all MFC structures. At that point, your problems are so serious that the impact
on CString is hardly noticeable; it is usually just the first victim of this problem.
****
>
>You shouldn't have problems but you have to keep it in the back of
>your mind for any heap related issues.
****
The same problem applies to the C runtime library with malloc and free. It is not unique
to C++ or MFC runtimes. A simple LPTSTR can fail just as badly.
joe
****
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm