> You don't need a separate header, you can just do #include "foo.moc" at the end.
I was talking about verdigris for which you have to do #include "wobjectimpl.h"
> I'd be interested in knowing in which way it is no longer c++, considering Q_OBjECT, signals, slots, ... are just plain cpp macros (see qobjectdefs.h).
If it was pure C++ then I would not need to run a MOC to generate working executables.
While they are also plain CPP macros they have semantics which is only understood by the MOC and is not captured by CPP or C++. This additional semantics is the reason why they are used in the first place because if it was not for the additional semantics again you would not need MOC.
All my types (and `#define`s) have some semantic meaning only I and non of my tools understand.
It is nice if a tool understands those and for an `emit` suggests only my signals for auto-completion, but if it lists them along all other members it is fine.
So I can see the argument from a puristic view, but in practice, once my built is setup to run it (cmake automoc or something), it simply works.
My issue with Qt is that the API design comes from days very long ago, where they did fantastic work on keeping compatibility, while not adopting to "modern C++" which always requires me to rethink the way I write code. Also integrating with non-Qt code isn't always easy due to reliance on QString (which has value Unicode features), QList (which meanwhile has many std-like APIs) etc. which easily travel through all layers. Thus when staying inside At it's really nice and quite consistent, but integrating is hard.
> All my types (and `#define`s) have some semantic meaning only I and non of my tools understand.
If it is not semantics essential to the correct operation of your program then this is a different matter. I really am not sure what the contention here or misunderstanding is.
When I write C++ I write it for a C pre-processor and C++ compiler to read in order to obtain a output program which does something specific and in line with the C++ standard.
This is not some high minded purism - this is just pragmatic reality.
If I write something in my source which I expect to result in specific output but the specific output cannot be obtained if I use a standard compliant C Preprosessor and C++ Compiler then either my expectation is wrong or I'm writing something which is not C++.
So if you don't rely on the behaviour that results from MOC being part of the toolchain then sure - you are writing C++ - if you do - it is not C++.
If the semantics (in a sense where it actually affects output) is part of a language, which it is, then changing the semantics of the language makes it a different language.
> So I can see the argument from a puristic view, but in practice, once my built is setup to run it (cmake automoc or something), it simply works.
> When I write C++ I write it for a C pre-processor and C++ compiler to read in order to obtain a output program which does something specific and in line with the C++ standard.
It generates output but the output is wrong in the sense that when I wrote Q_OBJECT I expected the output to be the result of (MOC -> CPP -> CXX) and not just (CPP -> CXX).
So put differently I expected Q_OBJECT (and what it expands to) to have semantic meaning which is not provided by a standard compliant C Preprosessor and C++ Compiler.
And if it was valid output - i.e. the output is the entirety of what I expected from the input - then I would not need to ever use MOC.
Moc just adds some more generated code next to you valid C++ code, generally in a new translation unit.
That generated code is just boiler plate which you could write by hand if you wanted. In a sense this is what verdigris does: it provides macros that makes makes it easier to "write it by hand" (the W_OBJECT_IMPL macro somehow expends to the code generated by moc)
> Moc just adds some more generated code next to you valid C++ code
Code without which the complete output of your toolchain from your source is incomplete and therefore invalid - again if this was not the case you would not need to run MOC at all.
> the output is wrong in the sense that when I wrote Q_OBJECT I expected the output to be the result of (MOC -> CPP -> CXX) and not just (CPP -> CXX).
That is not really how moc works though ? moc does not change anything to your original sources nor their translation units; it is not an additional preprocessing step, but a parallel one.
This .o is exactly the same that one that would be produced in a complete Qt program. Moc just generates additional source files with the implementation of some functions whose declaration is given by the Q_... macros. You could also write them by hand or generate them with fancy cmake scripts... it's just not a fun experience.
> moc just generates additional source files with the implementation of some functions whose declaration is given by the Q_... macros.
But those additional source files are essential to the operation of my program - if they werent - and it was just entirely optional - why would someone ever opt to run it?
> it is not an additional preprocessing step, but a parallel one.
If I write something and I use QT MOC specials like Q_OBJECT and I do no MOC processing occurs I will never obtain the output I consider as correct as a whole - sure if I don't care about the output as a whole and just look at parts of it then I could say those parts there and correct. But I did not write Q_OBJECT because I like the way it looks in my source file, I wrote it so that MOC could generate some specific code without which my program will not function correctly.
> This .o is exactly the same that one that would be produced in a complete Qt program.
Say I had a program (XPP) that for all valid c++ input generates the output that a c++ compiler would generate for:
// blank
Would it be a C++ compiler? And if not why not? I could also tell people that the .o file it generates is the same as would be produced by a c++ compiler except there is some additional parts which they can write by hand in the .o file.
When I write c++ I don't just care that some output is generated - if the output is just missing some parts it is still wrong - even if I could go add those parts by hand.
Similarly if I write Qt, I actually care very much that when I put Q_OBJECT that some things end up in the output - because if I did not I would not use MOC.
I was talking about verdigris for which you have to do #include "wobjectimpl.h"
> I'd be interested in knowing in which way it is no longer c++, considering Q_OBjECT, signals, slots, ... are just plain cpp macros (see qobjectdefs.h).
If it was pure C++ then I would not need to run a MOC to generate working executables.
While they are also plain CPP macros they have semantics which is only understood by the MOC and is not captured by CPP or C++. This additional semantics is the reason why they are used in the first place because if it was not for the additional semantics again you would not need MOC.