[GH-ISSUE #190] Incompatible LPWSTR typedef #125

Closed
opened 2026-05-05 11:05:48 -06:00 by gitea-mirror · 7 comments
Owner

Originally created by @shartte on GitHub (Apr 13, 2020).
Original GitHub issue: https://github.com/qmlnet/qmlnet/issues/190

This is more of a question/discussion than an actual bug.

Why is LPWSTR typedef'd to be char16_t rather than wchar_t?
I can guess why. wchar_t's size is implementation defined, but UnmanagedType.LPWStr guarantees 2-byte per character.

The issue that arises from typedefing LPWSTR in QMLNet's headers is that if it is mixed with code that includes windows.h, it will not compile anymore, since wchar_t and char16_t are NOT interchangeable:

qmlnet\src\native\QmlNet\QmlNet.h(12): error C2371: 'LPWSTR': redefinition; different basic types
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\winnt.h(472): note: see declaration of 'LPWSTR'

If there's no other reason for it, I'd propose changing the native method declarations over to const char16_t* and removing the typedef. I am willing to make the PR for that ofcourse.

Originally created by @shartte on GitHub (Apr 13, 2020). Original GitHub issue: https://github.com/qmlnet/qmlnet/issues/190 This is more of a question/discussion than an actual bug. Why is LPWSTR typedef'd to be char16_t rather than wchar_t? I can guess why. wchar_t's size is implementation defined, but `UnmanagedType.LPWStr` _guarantees_ 2-byte per character. The issue that arises from typedefing LPWSTR in QMLNet's headers is that if it is mixed with code that includes windows.h, it will not compile anymore, since wchar_t and char16_t are _NOT_ interchangeable: ``` qmlnet\src\native\QmlNet\QmlNet.h(12): error C2371: 'LPWSTR': redefinition; different basic types C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\winnt.h(472): note: see declaration of 'LPWSTR' ``` If there's no other reason for it, I'd propose changing the native method declarations over to `const char16_t*` and removing the typedef. I am willing to make the PR for that ofcourse.
Author
Owner

@pauldotknopf commented on GitHub (Apr 13, 2020):

I don't have a problem with that. Either change everything to const char16_t*, or create our own typedef that doesn't collide with windows.h.

<!-- gh-comment-id:612994384 --> @pauldotknopf commented on GitHub (Apr 13, 2020): I don't have a problem with that. Either change everything to ```const char16_t*```, or create our own ```typedef``` that doesn't collide with ```windows.h```.
Author
Owner

@shartte commented on GitHub (Apr 13, 2020):

Just for completeness sake: I just checked QString::fromUtf16 again, and it says the following:

This function is slow compared to the other Unicode conversions. Use QString(const QChar *, int) or QString(const QChar *) if possible.

Does anyone know why that is?

<!-- gh-comment-id:613017635 --> @shartte commented on GitHub (Apr 13, 2020): Just for completeness sake: I just checked [QString::fromUtf16](https://doc.qt.io/qt-5/qstring.html#fromUtf16-1) again, and it says the following: > This function is slow compared to the other Unicode conversions. Use QString(const QChar *, int) or QString(const QChar *) if possible. Does anyone know why that is?
Author
Owner

@pauldotknopf commented on GitHub (Apr 13, 2020):

Not me :)

<!-- gh-comment-id:613023384 --> @pauldotknopf commented on GitHub (Apr 13, 2020): Not me :)
Author
Owner

@vadi2 commented on GitHub (Apr 13, 2020):

Thiago on #qt might know.

<!-- gh-comment-id:613024559 --> @vadi2 commented on GitHub (Apr 13, 2020): Thiago on #qt might know.
Author
Owner

@shartte commented on GitHub (May 23, 2020):

@pauldotknopf Thinking about this some more: Why don't we just use QChar* directly?
We don't actually do any conversion on the raw character data and it would save us the nasty reinterpret_cast that's otherwise needed.
Ofcourse the docs say "Most compilers treat it like an unsigned short." without actually specifying what "most" means. Although we might guard against this with a static_assert(sizeof(QChar) == 2).
The char16_t constructor certainly makes it look like we can just use them interchangeably:

Q_DECL_CONSTEXPR QChar(char16_t ch) noexcept : ucs(ushort(ch)) {} // implicit
<!-- gh-comment-id:633132140 --> @shartte commented on GitHub (May 23, 2020): @pauldotknopf Thinking about this some more: Why don't we just use QChar* directly? We don't actually do any conversion on the raw character data and it would save us the nasty reinterpret_cast that's otherwise needed. Ofcourse the docs say "Most compilers treat it like an unsigned short." without actually specifying what "most" means. Although we might guard against this with a static_assert(sizeof(QChar) == 2). The `char16_t` constructor certainly makes it look like we can just use them interchangeably: ``` Q_DECL_CONSTEXPR QChar(char16_t ch) noexcept : ucs(ushort(ch)) {} // implicit ```
Author
Owner

@pauldotknopf commented on GitHub (May 26, 2020):

I'm not sure. I always thought QChar wasn't blittable with standard char16_t, but it looks like I'm wrong.

<!-- gh-comment-id:634110038 --> @pauldotknopf commented on GitHub (May 26, 2020): I'm not sure. I always thought ```QChar``` wasn't blittable with standard ```char16_t```, but it looks like I'm wrong.
Author
Owner

@shartte commented on GitHub (May 29, 2020):

Fixed by #203

<!-- gh-comment-id:636112125 --> @shartte commented on GitHub (May 29, 2020): Fixed by #203
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/qmlnet#125
No description provided.