How windows APIs accept strings - c++

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?

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.

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*?

Related

How to fix " State Error (active) E0513 a value of type “const wchar_t *” cannot be assigned to an entity of type “wchar_t *”"

I am trying to change the properties of a file using C ++
what am I doing wrong ?
The code is completely taken
https://learn.microsoft.com/en-us/windows/win32/stg/writeread-sample
propspec.ulKind = PRSPEC_LPWSTR;
propspec.lpwstr = L"Property Name";// this line problem
propvarWrite.vt = VT_LPWSTR;
propvarWrite.pwszVal = L"Property Value"; // this line problem
As the error message tells already: String literals are of type const char[] or const wchar_t[] (depending on underlying type), and you cannot legally assign an array of const to a pointer to non-const (some compilers accept such code, though, just emitting a warning), solely the other way round is allowed.
Question is now, how to get out of that dilemma?
In general:
If you are 100% sure (really, not the very least doubt!) that the strings won't get modified, you could just cast the const away:
wchar_t* ptr = const_cast<wchar_t*>(L"...");
If you have the least doubt about (modifications of string literals are undefined behaviour!), then copy the literal into an array:
wchar_t value[] = L"...";
ptr = value;
At this point, you need to be sure that the called function won't take ownership of the string, though: Would it try to free the string? Would it store the pointer somewhere for later usage, such that the array pointed to must live longer than the scope of the calling function?
If so, you might need to use a global array or malloc memory to copy the string to...
In specific case:
If you peek into the documentation of read and write functions, you see that the structs in question are passed to const parameters. Well, actually, that will make the pointer constant, not the data pointed to, still it looks pretty much safe to assume that the strings won't get modified (if need be, copied to somewhere – well, written to some file), so you actually should be fine with the const_cast option.
Side note: The example doesn't free the strings read back again; pretty interesting now the question for ownership (who will free them again)? Unfortunately, the documentation is not precise about...

Handle , Void Pointer , Objects in C++

So I was reading the article on Handle in C and realized that we implement handles as void pointers so "whatever" Object/data type we get we can cast the void pointer to that kind of Object/data and get its value. So I have basically two concerns :
1.If lets say in following example taken from Handle in C
typedef void* HANDLE;
int doSomething(HANDLE s, int a, int b) {
Something* something = reinterpret_cast<Something*>(s);
return something->doit(a, b);
}
If we pass the value to the function dosomething(21,2,2), does that mean the value HANDLE points to is 21, if yes how does any object when we type cast it to that object, will it be able to use it, like in this example, so in otherwords where does pointer to the object Something, something, will store the value 21.
2.Secondly the link also says "So in your code you just pass HANDLE around as an opaque value" what does it actually mean? Why do we "pass handle around"? If someone can give more convincing example of handles that uses objects that will be great!
1.: A handle is an identifier for an object. Since "21" is no object, but simply a number, your function call is invalid. Your code will only work if 's' really points to a struct of type Something. Simply spoken, a handle is nothing than a pointer is nothing than a memory address, thus "21" would be interpreted as a memory address and will crash your program if you try to write to it
2.: "Opaque value" means that no developer that uses your code can't take any assumptions about the inner structure of an object the handle identifies. This is an advantage over a pointer to a struct, where a developer can look at the structure and take some assumptions that will not be true anymore after you changed your code. "Pass around" simply means: assigning it and using it as a function call parameter, like in:
HANDLE s = CreateAnObject();
DoSomethingWithObject( s );
HANDLE t = s;
etc.
By the way: In real code, you should give handles to your objects different names, like EMPLOYEE_HANDLE, ORDER_HANDLE etc.
A typical example of a handle are window handles in Windows. They identify windows, without giving you any information about how a "Window" memory structure in the operating system is built, therefore Microsoft was able to change this inner structure without the risk of breaking other developer's code with changes to the "Window" structure.
I didn't realize there was one defacto article on HANDLEs or a defacto way to implement them. They are usually a windows construct and can be implemented any way some developer from 1985 decided to implement them.
It really has as much meaning as "thingy", or rather "thingy that can be used to get a resource"
Do not get into the habit of creating your own "handle" and certainly do not try to mimic code idioms from 1985. Void pointers, reinterpret_casts, and HANDLE are all things that you should avoid at all costs if possible.
The only time you should have to deal with "HANDLE" is when using the Windows API in which case the documentation will tell you what to do with it.
In modern C++, if you want to pass objects around, use references, pointers, and smart pointers(including unique_ptr, shared_ptr, weak_ptr) and study up on which scenarios call for which.
If we pass the value to the function dosomething(21,2,2), does that mean the value HANDLE points to is 21,
No. It just means that value of the void* is 21. If you treat 21 as the value of a pointer to an object of type Something, it will most likely lead to undefined behavior.
2.Secondly the link also says "So in your code you just pass HANDLE around as an opaque value" what does it actually mean? Why do we "pass handle around"? If someone can give more convincing example of handles that uses objects that will be great!
A handle is opaque in the sense that you cannot see anything through it. If a handle is represented by a void*, you can't see anything about the object since a void* cannot be dereferenced. If a handle is represented by an int (as an index to some array defined elsewhere in your code), you can't look at the value of the handle and make any sense of what the corresponding object represents.
The only way to make sense of a handle is to convert it a pointer or a reference using a method that is appropriate for the handle type.
In the case where a handle is represented by a void*, the code you have posted illustrates how to extract a pointer to a concrete object and make sense of the object.
In the case where a handle is represented by an int, you may see something along the lines of:
int doSomething(HANDLE s, int a, int b) {
// If the value of s is 3, something will be a reference
// to the fourth object in the array arrayOfSomethingObjects.
Something& something = arrayOfSomethingObjects[s];
return something.doit(a, b);
}

Should I forget dynamic memory allocation and pointers and always pass by v?

I have noticed that most C++ experts always advice it's better to pass by value, due to RVO. This allows me not worry too much about pointer manipulation and is easier to write code as well. No complaints there. This makes me wonder whether it is the correct approach to not use dynamic memory allocation (on the heap) at all and always pass parameters and return results by value?
This means instead of coming up with signatures like this:
Character* getCharacter(Sprite *sprite, Action* action)
I should more or less stick to signatures like:
Character getCharacter(Sprite sprite, Action action)
Is my understanding correct? or did I juth think i thaw a putthy cath?
They each have there pro's and con's. remember that using words like "always" is an absolute. Only the Dark Side deals in absolutes.
So let's look at each way and when we would use them.
Pass by value is good when the object being passed is smaller (since a local copy gets made). It is also good if you want to be sure to not accidentally change the original data. Its shortcoming is it makes a local copy and that can be bad if it is really big.
Pass by reference only passes a memory address. Therefore, large objects can be passed for a relatively low footprint. Also, with a reference, you can modify the original (this is both good and bad). This enables you to "return" more than one variable (so to speak). So obviously, the big con here is that you can mistakenly change the original data.
Constant pass by reference is generally accepted to be a very strong candidate for doing things. It has the pros of both pass by reference and value. Low footprint since it is a reference AND you can't change the original. There aren't many cons accept for the fact that your use of the variable in the method needs to change a little. Remember, its a const and therefore cannot be modified in the function.
Remember, there is no magic-bullet. Nothing is always better. Determine what you need and select the right tool for the job.
EDIT: also, has been said. Passing is not the same as dynamic allocation. dynamic allocation only happens with the "new" keyword. My suggestion would be to avoid the "new" keyword for now until you have a better understanding of arguments and pointers.
Whether or not you allocate an object on the heap typically is driven by one of the following concerns:
If the new object needs to outlive the function that creates it, the object must be allocated on the heap.
If the object is very large, and does not fit on the stack, then you must allocate it on the heap.
Beyond that, the choice of pass by value or pass by reference is determined by the semantics. If you want to operate on a copy, pass by value. If you want to operate on the actual object, pass by reference.
Your statement is simply utterly untrue. There is some light advice to pass by value instead of the mainstream const-ref in the special case where the function will copy the argument to a local variable anyway.
And for passing by-nonconst-pointer, pass by value was never an alternative. The first implies an optional out or inout param and the second and input param.
And mentioned dynamic allocation in question title just fits no way with the content.
Your understanding in definitely not correct.

Should my functions accept pointers or smart pointers?

I've started making use of std::unique_ptr e.g.:
unique_ptr<TFile> myfile( TFile::Open("myfile.root") );
instead of
TFile * myoldfile = TFile::Open("myoldfile.root") ;
Now I'm not sure what my functions should look like. I think part of the problem might be that my code is not complicated enough yet for any problems to become apparent but I'd like to get it right now so I don't end up in a mess when things are more complicated.
I used to have:
double interestingResult( TFile * input )
{...}
(which doesn't actually modify TFile but can't be const because it calls some non-const functions of TFile).
I could still call this by doing:
myResult = interestingResult( myfile.get() );
which doesn't seem very user friendly. (I think it is suggested here: https://stackoverflow.com/a/5325560/1527126 .)
Or I could modify my function to look like:
double interestingResult( unique_ptr<TFile>& input )
{...}
which forces the user to always use a unique_ptr.
or I could support both by writing:
double interestingResult( unique_ptr<TFile>& input )
{ return interestingResult( intput.get() ); }
but I don't see that in other people's code.
What is the standard approach to this situation?
I think this answer (https://stackoverflow.com/a/9700189/1527126) implies I should accept references since I don't expect myfile to be null. But the library function TFile::Open always returns a pointer so it seems natural to be able to pass that straight into the function without extra dereferencing.
Apologetic p.s. I gave up trying to work out whether I should ask on StackOverflow or CodeReview or not at all but please point me to the appropriate place if this is not it.
The answer you are referring to is the right one.
If you have a function that should work on any existing TFile instance and has no reason to accept NULL pointers as a valid argument and where the function argument does not carry ownership, you should use TFile& as parameter type (TFile const& where possible). That the object being passed in is held by pointer (with or without ownership) by the caller should not make a difference to that function.
You could choose to use a TFile * argument, but that creates at least ambiguity over validity of passing NULL, so may cause problems in the future.
If you use a unique_ptr<TFile> argument, you pass ownership of the object into the function for good. The caller will be left with a NULL unique_ptr when the call returns.
If you use a unique_ptr<TFile>& argument, this indicates that the function can choose to take over ownership of the object or leave it to the caller. Rather unusual.
A unique_ptr<TFile> const& argument could be used like a TFile *, but forces the caller to own the object and to manage it using a unique_ptr. Why should such a requirement be imposed on the caller? Of course this (and the other uses of unique_ptr) all also have to deal with the NULL case.
The problem with accepting smart pointers in the parameter list is you dictate what kind of smart pointer the caller can use. For example, by using unique_ptr you prevent the caller from using a shared_ptr instead.
In your case, I'd suggest a reference parameter. I also see regular pointers used a lot as well. The main thing is that your function doesn't try to hold a reference / take ownership of the object after the function returns - i.e. it's not later responsible for freeing the memory.
Either a reference TFile & or a pointer TFile * is fine.
There are people who will tell you that you "should" use a reference when a null pointer is an invalid input to the function. These people become confused and angry when they try to use standard functions like std::strlen, std::memcpy etc, inherited from C. My feeling is that while it's quite nice to use references to self-document that a referand is required, it's also quite nice to have your API work either consistently with references or consistently with pointers.
There are people who will tell you that you "should not" use a non-const reference parameter, preferring a pointer. They become confused and angry when they try to use standard functions like std::swap, because to a C programmer that looks like pass-by-value and so it "should not" modify the input.
As long as you don't work with either of those people, you can make your own choice.
It depends, but using raw pointers(or references to object) in functions prefered, because functions do not take ownership of pointer.
And also if one day you'll decide to use shared_ptr's...

Should the caller initialize "out" parameters?

Many Win32 API functions have parameters specified to be "out". For example, GetIconInfo() description says about the second parameter that The function fills in the structure's members.
This implies that the function doesn't ever read the original values stored in the "out" parameter - only changes them - and therefore the caller is free to skip initialization.
Yet in one project I see the following:
ICONINFO ii;
::SecureZeroMemory(&ii, sizeof(ICONINFO));
if (::GetIconInfo(hIcon, &ii))
{
//do stuff, then
//release bitmaps
if(ii.hbmMask)
::DeleteObject(ii.hbmMask);
if(ii.hbmColor)
::DeleteObject(ii.hbmColor);
}
Is there any sense in that SecureZeroMemory() call? What could happen without it?
Well, in general I think initialisation is not needed, but good practice if you don't know exactly what the called function does with the values in the output variable.
In this specific case, the ICONINFO structure has two HBITMAP members which are essentially pointers to bitmaps. In the general case I'd say that if you are passing pointers to a function then you have to be certain that:
You pass in pointers that point to nothing and the
function you call creates the thing
pointed to for you and makes sure
your pointer points to it. (and probably leaves you to manage the newly allocated stuff) or
You pass in a pointer that points to
something (i.e. you allocated something for it) and the
function uses what you allocated.
The GetIconInfo() function fits the first case. So for clarity and perhaps even security it looks like a good idea to me to ensure the HBITMAP members of the ICONINFO structure are actually zero, rather than a random value that can lead to all kinds of nastiness further down the road.
So my verdict in this case would also be: not necessary but good practice.
Nothing. I mean if one is pretty sure that whatever is written there before call is discarded then there is no reason for doing that. But we don't know how internally the API will
function unless we developed the API, then it would be a good idea to initialize it.
This implies that the function doesn't ever read the original values stored in the "out"
parameter - only changes them - and therefore the caller is free to skip initialization.
Perhaps it isn't about the function reading the fields. Maybe its for detecting fields unfilled by the function? I don't know if this is necessary in this case, just pointing out that it might not be about reading.