How does clang know that qFatal is a kind of return from a function?
-
I have a project that uses qFatal at the end of some functions to says "if we got here, something is seriously wrong, and we better blow up than try to continue". On Windows, using clang from Visual Studio, I get this warning:
warning: non-void function does not return a value in all control paths [-Wreturn-type]
In other build environments that I use, clang correctly sees qFatal as an exit point, no warning. How does that work?
-
When you follow the macro you will find this in QMessageLogger class:
#ifndef Q_CC_MSVC Q_NORETURN #endif Q_DECL_COLD_FUNCTION void fatal(const char *msg, ...) const noexcept Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
And since you compile with clang-cl (I doubt you use clang) Q_CC_MSVC is defined and therefore Q_NORETURN is not visible.
But since nowadays Q_NORETURN (aka__declspec(noreturn)
for msvc) is available also for msvc this looks like an oversight (the ifndef was added back in 2012)/edit: looks like Q_NORETURN was (not) yet added to qcompilerdetection.h for MSVC ... maybe needs a patch :)
-
Ok Q_NORETURN is properly defined for MSVC but qt_message_fatal() isn't a noreturn function on windows - at least not in debug mode - see qlogging.cpp. Therefore it is not marked as 'noreturn' for MSVC.
-
Hi, out of curiosity and to add what @Christian-Ehrlicher said, I run this Qt app on 4 compilers:
#include <qdebug.h> int main() { qDebug() << QT_STRINGIFY(Q_NORETURN); }
to see what the Q_NORETURN macro expands to:
on Windows Qt 6.3.1 MSVC 2019: __declspec(noreturn) on Windows Qt 6.3.1 MinGW 11.2.0: __attribute__((__noreturn__)) on Ubuntu 22.04 Qt 6.3.1 gcc 11.2.0: __attribute__((__noreturn__)) on Monterey 12.4 clang-1300.0.29.30: __attribute__((__noreturn__))
I also tested Q_NORETURN on Monterey/clang with this:
#include <qdebug.h> Q_NORETURN int goodbye(int i) { if ((i % 42) < 42) qFatal("CU on the other side"); } int main() { qDebug() << goodbye(rand()); }
If I comment out Q_NORETURN clang complains (correctly)
warning: non-void function does not return a value in all control paths.
But if I leave it in, clang now complains:
warning: function declared 'noreturn' should not returnSo that macro is not the most beginner-friendly one :-)
-
qFatal() is not a guaranteed exit point with Visual Studio. In Debug mode, the Visual C++ Runtime will display a "Debug Error!" dialog and give you 3 options: "Abort", "Retry", "Ignore". If you click "Ignore", your app will continue running.
That is why, if you are using the VC++ Runtime, you must still provide a return value after qFatal().