Post by Frans KlaverTo be honest I never really understood why one would insist on
compile-time checking of something that was obviously intended to be used
and checked at run-time.
It was never intended to be done only at runtime. It was done that way
originally because it was the only way it could be done.
Since then, moc has become useful and the syntax has solidified, so it hasn't
changed.
Post by Frans KlaverBottom line for me, though, is that I don't agree with the trade-off made
here: you're trading compiler checks on unintentionally messing about from
unrelated pieces of code for compiler checks on possible connections. One
What is worse for you, that someone unintentionally emits a signal, or that
you fail to connect because someone made a typo, or accidentally left the
variable names in the SIGNAL or SLOT definition. Not to mention in refactoring
this problem might creep in, because the code compiles but fails at runtime.
Don't forget you have to match *exactly* the signature, of the exact same
types, in the exact same typedef and namespace description.
You may say you're a very good developer and you check all connections (by
testing the return value or by running with QT_FATAL_WARNINGS=1). Are you sure
you tested all of the connection possibilities in your code? There is no
chance that there was a connect() call that went untested? How about your co-
workers, are they as good as you?
Post by Frans Klaverof the two is more likely to produce weird results, and my gut says a
solution with publicly accessible signals is the one. Get some bad signal
I beg to differ. I think the lack of compile-time checking that the connection
can succeed is the one causing most issues.
Post by Frans Klavernames, code completion, and your average lazy developer (are there
non-lazy devs?) and you're set. The simple fact is that public signals
doesn't discourage you from writing bad code. Isn't API design about just
that? Making writing good and predictable code easy and bad code harder?
otherObject->someSignal(arg1, arg2, arg3);
and the current
QMetaObject::invokeMethod(otherObject, "someSignal(int,int,int)",
arg1, arg2, arg3);
The first looks like your average piece of code and can easily be
overlooked, the second looks like messing around unless you know what
you're doing. When reviewing or debugging, I'd rather have the latter
piece of code, simply because it's suspiciously suspicious (and maybe even
wrong, didn't check that).
You know that we have a way of marking every line where we are emitting a
signal, right? We created a macro for this, it's called "emit".
If you need to muck around with the internals, you must have a good reason.
Then you might as well have a little more performance.
Not to mention that you made a serious mistake above by placing
"(int,int,int)": in invokeMethod, you do not list the signature. Imagine if
this were production code! It wouldn't work and it might go undetected for
years.
Post by Frans KlaverAs far as I understand, the string based versions for run-time defined
signals and slots are still required. Sticking to the old syntax will keep
a common syntax for both use cases. If a connection is vitally important
to the workings of the system I'd just use Q_ASSERT(connect(...)).
Detection guaranteed.
Also a VERY BAD idea. Q_ASSERT expands to empty in release builds. So if you
test in debug mode and everything works, when you compile in release mode
things will suddenly stop working!
So, tell me, after making two very big mistakes in one email due to the
current syntax, wouldn't you rather your compiler told you that you had made
mistakes?
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358