PDA

View Full Version : 'QChar::QChar(ushort) noexcept': member function already defined or declared



mbardet
28th July 2018, 22:17
I am using visual studio 2017 and getting this error when building my project with Qt 5.11.1. Any idea how to solve this?

ChristianEhrlicher
29th July 2018, 12:58
Looks like you're compiling your project with compiler switch /Zc:wchar_t- which treats wchar_t as simple ushort

mbardet
6th August 2018, 16:03
Thanks.
But when my project needs it otherwise it won't build. It used to work with qt 5.8. Is there a workaround in Qt without having to change my project?

d_stranz
6th August 2018, 20:27
Qt has been using the /Zc:wchar_t flag since 5.0 was released, and the binaries downloaded from the Qt web site have all been built that way. If you have been building your own Qt binaries, then you've been building them with the wrong flag setting.

ChristianEhrlicher
9th August 2018, 20:02
It should work by modifying the qstring header file - simply remove the problematic ctor.

d_stranz
9th August 2018, 22:28
It should work by modifying the qstring header file - simply remove the problematic ctor.

That's not a solution, that's a kludge. Changing the definition of a class means you now have a mismatch between Qt (which was built using the unmodified header) and application code (which was built with a different definition for QChar).

The /Zc:wchar_t vs. /Zc:wchar_t- issue is a fundamental difference and will affect every piece of code compiled and linked into the project, and will likely cause run-time errors as well. The correct approach would be to discover the source of the problem (which isn't in the Qt source code) and fix it there. Trust me, I've been there. You cannot mix and match the two language options. CHoose one or the other, and build -everything- to that choice.

ChristianEhrlicher
10th August 2018, 15:29
I'm sorry but that's not true. The wchar_t switch does not change the ABI in any way. It just says if wchar_t should be treated as ushort or not. Therefore it is save to link against a library compiled against another /Zc:wchar_t switch as long as you don't pass a wchar_t between the lib/executable.
But in the long term one should not mix those two.

d_stranz
10th August 2018, 17:06
as you don't pass a wchar_t between the lib/executable.

Which for any practical purpose is nearly impossible to avoid.

This kind of kludge might be fine for home-grown, single user projects, but it is unacceptable for commercial code. By kludging instead of actually solving the problem, it creates a maintenance and reliability issue. Someone will have to remember to "fix" that header file on every machine where the code is built, and remember to "fix" it again with every new release of Qt. Someone will also have to remember to tell every developer who works on the project, to make sure they don't accidentally try to pass a wchar_t variable into Qt or vice-versa, or use any third-party library that does the same. Years from now when the original developers have moved on but there are still bugs to fix, someone has to remember or be forced to waste time discovering why the new code has led to a compilation or regression test failure.

ChristianEhrlicher
25th August 2018, 07:47
The (more or less) exact change I proposed is now in official Qt: https://codereview.qt-project.org/#/c/235144/
No need to hack the header file with Qt5.11.2 / Qt 5.12 anymore ...

d_stranz
25th August 2018, 23:16
Not exactly. The change you suggested only comes into play when someone -uses- the header containing the QChar constructor. In that case library still contains code with an inconsistent definition of wchar_t. The change to the Qt sources affects not only the use of the header but the library build itself so that everything is now internally and externally consistent.

In any case, if the size and layout of wchar_t and ushort are the same regardless of the compiler flag, it probably doesn't make any difference in fact. I do know that if you try to mix stdlib code (particularly std:: wstring) with QString code where Qt was compiled with a different version of the flag from the code that uses wstring, you get link-time errors because the mangled names of the functions do not match.

ChristianEhrlicher
26th August 2018, 09:53
It's an inline ctor, you won't find any code inside the Qt library for it...
/edit: therefore it will even work when you compile Qt with /Zc:wchar_t- and your lib with /Zc:wchar_t+ or the other way round.

d_stranz
26th August 2018, 17:25
OK, I guess because this is a non-virtual method, it is resolved statically at compile-time and thus has no effect on either the class layout or the vtable. If the library is compiled with the code in place, it will generate a reference to a method that is never called externally by a caller using code compiled with the constructor commented out.

It is still hard for me to believe you can mix and match code from Qt, an app, and third-party libraries using different values for the flag and not end up getting into trouble somewhere.