Question

I have to admit this has always confused me how certain windows API accept strings. Take for example SetWindowText(). Now any function which takes a pointer to anything typically means it doesn't store that object but merely use the pointer that is passed. Therefore the caller has the responsibility to make sure the object passed to it exist for whenever it may be needed. Now what would you expect the final message that will be printed out below?

TCHAR * label = new TCHAR[50]();
_tcscpy( label, _T("allocated string") );
m_wndStaticLabel.SetWindowText( label );
_tcscpy( label, _T("string has changed") );

Theoretically I would expect it to print "string has changed" but it prints "allocated string". Similarly:

CString label = _T("CString Label");
m_wndStaticLabel.SetWindowText( label );

In this case a pointer of a local variable 'label` is being passed to it but still no problem. The control always prints the right string even though it received pointer of string allocated on stack.

This implies that the control actually allocate its own memory and assign that to the control instead of the pointer we are passing but this fact is never documented. Isn't this a little misleading? When I am passing a pointer to a function, one thing I immediately remind myself is I shouldn't be destroying it until the function returns but it is not the case in this case and it is not documented either.

So my question ultimately is this simply lack of documentation or there is something else to it when we passing a pointer to an object but it essentially behaves like we have passed object by value?

Was it helpful?

Solution

Remember that the Windows API is based on C conventions. This means that the only way to pass a string is as a pointer to the first character. None of the functions accept a CString or std::wstring for example, except by implicit conversion to a const wchar_t *.

You are right to be concerned about whether a copy of the pointer is retained by the control, but rest assured that it doesn't. The documentation doesn't mention this, it's assumed by default - if the pointer was retained, there would be a note about it. You'll find that some handles are documented in this manner.

OTHER TIPS

I think all windows API functions that take pointers will only use the pointers while running, but never store them (except for special documented cases). When the data is needed later, a copy is made.

The problem if a function would store the pointers would be that the system is taking ownership of the objects, and thus would be responsible for freeing them. But then the functions would need to know how the objects were allocated - there are many possibilities.

I usually also adhere to this principle in my own functions.

In C++, arrays decay to pointers when passed as function arguments, so the prototype is exactly as it should be -- a pointer to a TCHAR. Otherwise, how do you suggest the function prototype for SetWindowText() be written?

In addition, look at your code sample. You overlooked the _tcscpy() function and concentrated solely on SetWindowText(). Given your reasoning, how is _tcscpy() supposed to behave when given a TCHAR*?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top