0

What means size in TCHARs from msdn?

For example:

The size of the lpFilename buffer, in TCHARs.

If i have a buffer:

WCHAR buf[256];

So i need to pass 256, or 512? _tsclen(buf) or sizeof(buf)?

Solid Coder
  • 149
  • 9
  • 1
    256, _tsclen(buf), or can say sizeof(buf)/sizeof(TCHAR) – RbMm Jul 14 '16 at 20:01
  • 1
    This is a case, where [Hungarian Notation](https://en.wikipedia.org/wiki/Hungarian_notation) is helpful. Most Windows API calls use the `cch` prefix to specify the *Count of CHaracters*, while a `cb` prefix is used for the *Count of Bytes*. *"The size [...] in TCHARs"* is the same as the *count of characters*. In other words: Use `_tcslen`. – IInspectable Jul 15 '16 at 11:46

1 Answers1

3

sizeof is always in chars, which is equivalent to saying it's always in bytes. TCHARs are not necessarily chars, so sizeof is the wrong answer.

Using tsclen(buf) is correct if you want to pass the length (in TCHARs) of the string in the buffer. If you want to pass the length of the buffer itself, you can use sizeof(buf)/sizeof(TCHAR) or, more generally, sizeof(buf)/sizeof(buf[0]). Windows provides a macro called ARRAYSIZE to avoid typing out this common idiom.

But you can only do that if buf is actually the buffer and not a pointer to a buffer (otherwise sizeof(buf) gives you the size of a pointer, which is not what you need).

Some examples:

TCHAR buffer[MAX_PATH];
::GetWindowsDirectory(buffer, sizeof(buffer)/sizeof(buffer[0]));  // OK
::GetWindowsDirectory(buffer, ARRAYSIZE(buffer));  // OK
::GetWindowsDirectory(buffer, _tcslen(buffer));  // Wrong!
::GetWindowsDirectory(buffer, sizeof(buffer));  // Wrong!

TCHAR message[64] = "Hello World!";
::TextOut(hdc, x, y, message, _tcslen(message));  // OK
::TextOut(hdc, x, y, message, sizeof(message));  // Wrong!
::TextOut(hdc, x, y, message, -1);  // OK, uses feature of TextOut

void MyFunction(TCHAR *buffer) {
  // This is wrong because buffer is just a pointer to the buffer, so
  // sizeof(buffer) gives the size of a pointer, not the size of the buffer.
  ::GetWindowsDirectory(buffer, sizeof(buffer)/sizeof(buffer[0]));  // Wrong!

  // This is wrong because ARRAYSIZE (essentially) does what we wrote out
  // in the previous example.
  ::GetWindowsDirectory(buffer, ARRAYSIZE(buffer));  // Wrong!

  // There's no right way to do it here.  You need the caller to pass in the
  // size of the buffer along with the pointer.  Otherwise, you don't know
  // how big it actually is.
}
Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175
  • Read my question again. You are saying that tsclen(buf) if i want to pass length. I am asking: WHAT neccessary i want to pass: a length of the string, or a length of the buf. So what i need to do: tsclen(buf) or sizeof(buf)/sizeof(buf[0]) if it required to " The size of the lpFilename buffer, in TCHARs. ". ??? – Solid Coder Jul 14 '16 at 20:19
  • This is a good answer and Adrian does not need to read the question again. – David Heffernan Jul 14 '16 at 20:20
  • There's also `_countof` - I'm not sure what the difference is between this and `ARRAYSIZE`. – Harry Johnston Jul 15 '16 at 01:40
  • 1
    @HarryJohnston: I believe the only difference is, that they produce different error messages when used on something that isn't an array. This is for C++. When compiling C code, their implementation is identical. – IInspectable Jul 15 '16 at 11:49