Qt - moc causing C2504: base class undefined - qt

I'm having a problem that I've been trying to solve for a while, but I am completely stumped. So I have two classes, X and Y, and they each have their own header files, X.h and Y.h. Each is a Q_OBJECT and has that macro definition in the header file.
class Y: public X { Q_OBJECT ...}
The definition of Y reads. The definition of X reads:
class X: public QGLWidget {Q_OBJECT ...}
When I compile, X.cpp and Y.cpp compile correctly and there are no problems at that stage. The moc files are also generated with no problem.
However, when the standard QT build process goes to compile moc_X.cpp, it gives me "C:\path\Y.h(34) : error C2504: 'X' : base class undefined". But this doesn't happen when it's compiling Y.cpp or X.cpp, it only happens when it's compiling the moc files! Any ideas? That the build would be failing at the moc stage and only moc stage seems extremely peculiar. Help is much appreciated!

I've tried reproducing it, with the description you give, and haven't been able to.
So, here are things that would be worth checking:
errors in include guards?
Check that you haven't accidentally got 2 include-guards of the same name in 2 different headers (i.e. the #ifndef X_H and #define X_H lines)
(This is perhaps less likely, from your description: it would be more likely if the error was in the compiling of moc_Y.cpp)
forward declarations for types used in signals or slots?
Sometimes a parameter in a signal or slot can require an extra header to be included.
The best way I can explain it is to say that there are cases where your header would be fine with a forward-declaration to a class, but the moc can generate code that needs to actually create or destroy a type that your header only forward-declares.
If this is the case, there is a way to add code to the .ui, that requests inclusion of the extra header for the forward-declared type. But the easiest solution is just to replace the forward declaration with the appropriate header instead, inside X.h or Y.h.
check the contents of the moc_X.cpp file
If the above doesn't help, and if you haven't done so already, I'd suggest opening up the offending moc file and reading the code. Once you see what it's doing, it might give you some ideas.

Related

Frama-C aborted Invalid user input

I am very new to Frama-c and I got an issue when I am trying to open a C source file.
The error shows as
"fatal error: event.h: No such file or directory. Compilation terminated".
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i (no preprocessing)
[kernel] Parsing WorkSpace/bipbuffer.c (with preprocessing)
[kernel] user error: failed to run: gcc -E -C -I. -dD -D__FRAMAC__ -nostdinc -D__FC_MACHDEP_X86_32 -I/usr/share/frama-c/libc -o '/tmp/bipbuffer.ce6d077.i' '/home/xxx/WorkSpace/bipbuffer.c' you may set the CPP environment variable to select the proper preprocessor command or use the option "-cpp-command".
[kernel] user error: stopping on file "/home/xxx/WorkSpace/bipbuffer.c" that has errors. Add'-kernel-msg-key pp' for preprocessing command.
So bascially I am trying to open a C source file but it returns an error like this. I aslo tried other very simple C files like hello world and other slicing functions, it works well.
I thought it was because I didn't have the dependencies of 'event.h' but it still return these errors after I installed the libevent dependencies. I am not sure if I need to manually set some path of the dependencies for frama-c
Here is part of the C file (Source link: https://memcached.org/) that I would like to open:
#include "stdio.h"
#include <stdlib.h>
/* for memcpy */
#include <string.h>
#include "bipbuffer.h"
static size_t bipbuf_sizeof(const unsigned int size)
{
return sizeof(bipbuf_t) + size;
}
int bipbuf_unused(const bipbuf_t* me)
{
if (1 == me->b_inuse)
/* distance between region B and region A */
return me->a_start - me->b_end;
else
return me->size - me->a_end;
}
......
Thanks,
Compilers and other tools working with C source code need to know where to find header files. There are some standard places where they look automatically, but Frama-C has fewer of those than (and different ones from) a normal compiler.
You need to find out where event.h is installed, then pass something like -cpp-extra-args "-I /path/to/directory/" to Frama-C. Pass the directory name only, not including the name event.h itself.
In addition to Isabelle Newbie's answer, I'd like to point out that the Chlorine version of Frama-C, whose beta has been recently announced, features a new option -json-compilation-database that attempts to read the arguments to be passed to the pre-processor from a compilation database.
Such database can be generated directly by cmake, but there are solutions for make-based project such as the one you refer to, in particular bear, which intercepts the commands launched by make to build the database.
Here's a detailed summary of how you could proceed, using the new -json-compilation-database option from Frama-C 17 Chlorine, plus an extra script list_files.py (which is not in the beta, but will be available in the final 17 release, and can be downloaded here):
Get the source files you want to analyze with Frama-C, run ./configure, and if possible try to disable optional dependencies from external libraries; for instance, some code bases include optional dependencies based on availability of libraries/system features, but have fallback options (resorting to standard C library or POSIX functions). The more you give Frama-C, the better the chances of analyzing it well, so if such external libraries are not essential, excluding them might help get a more "POSIXy" code, which should help. This is typically visible in config.h files, in macros commonly named HAVE_*.
Compile and install Build EAR or some equivalent tool to obtain a compile_commands.json file.
Run bear make (or cmake with flag CMAKE_EXPORT_COMPILE_COMMANDS) to get the compile_commands.json file.
Run the aforementioned list_files.py in the directory containing compile_commands.json to obtain the list of C sources used during compilation.
Run Frama-C (17 Chlorine or newer), giving it the list of sources found in the previous step, plus option -json-compilation-database . to parse the compile_commands.json and, hopefully, get the appropriate preprocessing flags.
Ideally, this should suffice, but in practice, this is rarely enough. In particular due to the presence of external libraries and non-C99, non-POSIX functions, the following steps are always needed.
6. Inclusion of external libraries
At this step, Frama-C will complain about the lack of event.h. You'll have to include the headers of this library yourself. Note: copying headers directly from your /usr/include is not likely to work, due to several architecture-specific definitions, especially files such as bits/*.h..
Instead, consider downloading the external libraries and preparing them (e.g. running ./configure at least). Then manually add the extra include directory via -cpp-extra-args="-I <path/to/your/sources/for/libevent.h>/include".
7. Inclusion of missing non-POSIX headers
Some other headers may be missing, in particular GNU- or BSD-specific sources (e.g. sysexits.h). Get these headers and add them when necessary. The error message in this case comes from the preprocessor (gcc) and is similar to this:
memcached.c:51:10: fatal error: sysexits.h: No such file or directory
#include <sysexits.h>
^~~~~~~~~~~~
compilation terminated.
8. Definition of missing non-POSIX types and constants
At this point, all necessary headers should be available, but parsing with Frama-C may still fail. This is due to usage of non-POSIX type definitions (e.g. caddr_t, struct ling), non-POSIX constants (e.g. MAXPATHLEN, SOCK_NONBLOCK, NI_MAXSERV). Error messages typically resemble the following:
[kernel] memcached.c:3261: Failure: Cannot resolve variable MAXPATHLEN
Constants are often easy to provide manually, by grepping what's available in your /usr/include.
Type definitions, on the other hand, may require some copy-pasting at the right places, especially if they depend on other types which are also missing. This step is hardly automatizable, but relatively straightforward once you get used to some specific error messages.
For instance, the following error message is related to a missing type definition (caddr_t):
[kernel] Parsing memcached.c (with preprocessing)
[kernel] memcached.c:1074:
syntax error:
Location: line 1074, between columns 38 and 47, before or at token: c
1072 *hdr++ = 0;
1073 *hdr++ = 0;
1074 assert((void *) hdr == (caddr_t)c->msglist[i].msg_iov[0].iov_base + UDP_HEADER_SIZE);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1075 }
1076
Note that the token just before c is (caddr_t), which has never been defined (it is often defined as either void * or char *).
The following error message is related to an incomplete type, i.e., a struct used somewhere but never defined:
[kernel] memcached.c:5811: User Error:
variable `ling' has initializer but incomplete type
It means that variable ling's type, which is struct linger (non-POSIX), has never been defined. In this case, we can copy it from our /usr/include/bits/socket.h:
struct linger
{
int l_onoff; /* Nonzero to linger on close. */
int l_linger; /* Time to linger. */
};
Note: if there are POSIX constants/definitions missing from Frama-C's libc, consider notifying its developers, or proposing pull requests in Frama-C's Github.
9. Fixing incompatible and missing function prototypes
Parsing is likely to succeed after the previous step, but it may still fail due to incompatible function prototypes. For instance, you may get:
[kernel] User Error: Incompatible declaration for usleep:
different integer types int and unsigned int
First declaration was at assoc.c:238
Current declaration is at items.c:1573
This is the consequence of a warning emitted earlier:
[kernel:typing:implicit-function-declaration] slabs.c:1150: Warning:
Calling undeclared function usleep. Old style K&R code?
It means that function usleep is called, but it does not have a prototype, therefore Frama-C uses the pre-C99 convention of "implicit int": it generates such a prototype, but later in the code, an actual declaration of usleep is found, and its type is not int. Hence the error.
To prevent this, you need to ensure usleep's prototype is properly included. Since it is not POSIX.1-2008, you need to either define/undefine the appropriate macros (see unistd.h), or add your own prototype.
At the end, this should allow Frama-C to parse the files and build an AST.
However, there are several missing prototypes yet; we were just lucky that none conflicted with actual declarations. Ideally, you'll consider the parsing stage done when there are no more messages such as implicit-function-declaration and similar warnings.
Some of the missing prototypes in memcached, such as getsubopt, are POSIX and should be integrated into Frama-C's standard library. Others might make part of a small library of non-standard stubs, to be reused for other software.
Contributing with results for future reuse
Successful conclusion of the parsing stage for such open source libraries is enough to consider them for integration into this repository of open source case studies, so that future users can start their analyses without having to redo all of these steps. (The repository is oriented towards Eva, but not exclusively: parsing is useful for all of Frama-C plug-ins.)

C linkage and declaration error on include<QtNetwork>

I have the weird problem that when I include anything from the QtNetwork module into my Qt Desktop application, I get a bunch of errors, before anything of the included is even used.
For example, if I include QtNetwork/QHostAddress, I get the following errors:
..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include/QtNetwork/qabstractsocket.h:66: error: template with C linkage
..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include/QtNetwork/qabstractsocket.h:253: error: declaration of C function 'QDebug operator<<(QDebug, QAbstractSocket::SocketState)' conflicts with
..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include/QtNetwork/qabstractsocket.h:252: error: previous declaration 'QDebug operator<<(QDebug, QAbstractSocket::SocketError)' here
..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include/QtNetwork/qhostaddress.h:141: error: declaration of C function 'QDebug operator<<(QDebug, const QHostAddress&)' conflicts with
..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include/QtNetwork/qabstractsocket.h:253: error: previous declaration 'QDebug operator<<(QDebug, QAbstractSocket::SocketState)' here
..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include/QtNetwork/qhostaddress.h:148: error: declaration of C function 'QDataStream& operator<<(QDataStream&, const QHostAddress&)' conflicts with
..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include/QtNetwork/qhostaddress.h:141: error: previous declaration 'QDebug operator<<(QDebug, const QHostAddress&)' here
Of course, I added the line
Qt += network
to my .pro file, so this can't be the issue. Another module (opengl) could be included without problems.
I already ensured that nothing is wrong with my Qt installation itself by creating a dummy project which did nothing but including QtNetwork. It worked just fine.
So, there must be something wrong with my project, but as the error messages only occur in this special case I have no idea what information to provide for you.
All I can say is that the program was pure C-Code before and it is now being changed to C++ with Qt, so there is still a mix in it. But this does not seem to be a problem as long as QtNetwork is not included.
Any ideas on how to solve this or on what information is relevant for this problem?
I finally figured out my problem. The solution is quite easy:
I included QTNetwork into a header file, which in turn was included into some other .cpp-file by my team member, but he wrongly placed the include-statement in an extern "C" block, so that in the end QTNetwork was included as an extern "C" even though it is C++.
So, two lessons learned:
Don't rely on the correctness of your team mates' code.
If an include leads to errors, follow up the whole include chain to track down the problem.

Qt moc error 1 - what does it mean?

I'm trying to build a project on Mac OSX, and it's giving me a cryptic error:
[moc_droparea.cpp] Error 1
droparea.cpp is (obviously) a file in the project. I checked that it exists in the project directory and is not corrupted. The file moc_droparea.cpp doesn't show up in the build folder after this error, so I'm assuming it's failing to build for whatever reason, but the error is too vague to help me figure out what's going on. Could anyone help me figure out what this means please?
Click on "compile output", scroll up and click the red line.
In my case the Red line was saying: You cant define an integer value in private slots..
Under the qt creator window, in "progress details" section, there is a button named "compile output" (button number 4). Errors are explained there with red font. Click it and scroll up.
The solution was annoyingly simple. I had a folder structure that put spaces (illegal characters) in the file path. I put underscores instead of spaces and it built fine. I would think the moc pre-processor could handle spaces in file names, but apparently not. I feel foolish, but at least the problem is solved now.
Hopefully this solution can help someone else.
This can be because of few other things as others have mentioned. I would like to add another one which is missing here.
You will get a "moc error 1" in case you create a class and add Q_OBJECT to it but do not inherit from QObject.
If you take a look at Compile Output there is a line saying:
Error: Class contains Q_OBJECT macro but does not inherit from QObject
Hence, the general approach to fix this problem is just taking a look at "Compile Output" window.
This can be because of many things I guess - I had a similar situation where I forgot to remove an entry in the .qrc file that didn't exist anymore.
So check your resource paths as well.
You can right click on the error 1 and select 'View output'. In my case, I had a bad file name in my qrc file.
Like J.Javan already pointed to, it might be helpful to check also the compiler output. In my case I found:
../stateMaschine/usermenu.h:57: Error: Class declarations lacks
Q_OBJECT macro. make: *** [Makefile:215: moc_usermenu.cpp] Error 1
So this helped me to fix the error by correction of the class declaration when using signals and slots:
class Menu : public QObject{
Q_OBJECT
...
Same Error 1 occured to me due to a ressource file (.qrc) which referred to a file name beginning with a period. When I removed the period from the file name, compilation worked again. Interestingly, the error only occured under Mac OSX using the Clang compiler. On Windows using the gcc compiler, the file name did not provoke an error.
Maybe the "[source file name] Error 1" message in general means that a file could not be found due to unexpected characters in the file path.
In my case, I ran out of space on SD card causing this sort of error.

including Qt headers in DLL

I have a DLL in wich I would like to take a reference to a QObject and manipulate it, without actually creating an interface. So, I included "Qt/qobject.h" and compiled, but the compiler (Visual Studio 2008 pro) gives me syntax errors. It looks like it doesn't recognize the QThread object. How do I use a QObject in my dll? Is this even possible? Do I have to start my program from a Qt app? I'm actually trying to set a system-wide hook and get 3rd application QWidgets to manipulate... Any idea how I can use QObject in my dll?
Here are the errors:
1>------ Build started: Project: FroggerDLL, Configuration: Debug Win32 ------
1>Compiling...
1>FTClient.cpp
1>c:\qt-win-opensource-src-4.5.2\src\corelib\kernel\qobject.h(154) : error C2059: syntax error : 'type'
1>c:\qt-win-opensource-src-4.5.2\src\corelib\kernel\qobject.h(154) : error C2238: unexpected token(s) preceding ';'
1>c:\qt-win-opensource-src-4.5.2\src\corelib\kernel\qobject.h(155) : error C2144: syntax error : 'int' should be preceded by ')'
1>c:\qt-win-opensource-src-4.5.2\src\corelib\kernel\qobject.h(155) : error C2144: syntax error : 'int' should be preceded by ';'
1>c:\qt-win-opensource-src-4.5.2\src\corelib\kernel\qobject.h(155) : error C2059: syntax error : ')'
1>c:\qt-win-opensource-src-4.5.2\src\corelib\kernel\qobject.h(155) : error C2208: 'int' : no members defined using this type
1>FroggerDLL - 6 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 3 up-to-date, 0 skipped ==========
Any help would be greatly appreciated,
Thanks
Dave
What's on line 154? Mine is just the declaration
QThread* thread() const;
but that's 4.5.1 on Linux so it might be different. The first reference to anything involving the token type is on line 204 which is a variable of type Qt::ConnectionType.
BTW. I just tried compiling the following on my system ( in the file incqobj.cpp )
include <QOObject>
QObject myQOject;
with
g++ -I/usr/lib/qt4/include -I/usr/lib/qt4/include/QtCore -c incqobj.cpp
and it compiled fine so it should be as simple as that.
Edit: Since Jesse confirms that it works for him on Windows I'm tempted to say that you've got a non-Qt macro coming in and interfering. One thing you could do is a sanity check on what the compiler is actually seeing by getting VS to only produce the preprocessed source rather than do the compilation.
I haven't used VS in years but I think the option is \E maybe?
[Edit: see the 2nd comment by Jesse, it should be /E] It may also be an explicit option now in the compiler properties which can be set for that source file. Can't remember where it puts the output either so you may need to hunt around for it a bit! If you get that going though you can check to see if the code looks right at the part that would correspond to line 154 in the original QObject header.
Thanks for all the help, solution: I had to include the Qt headers before all my other includes, and it now compiles.
Thanks again!
Try including QThread?
#include <QThread>
Qt uses forward declaration extensively and sometimes you need to include extra headers.
EDIT:
Do you set any defines? Here is what I have for my 2003 Qt commercial (4.3.4) project (executable that links to Qt dlls):
QT_LARGEFILE_SUPPORT
QT_DLL
QT_GUI_LIB
QT_CORE_LIB
QT_THREAD_SUPPORT
QT_NETWORK_LIB

mingw spitting countless warnings about ignoring "dll import" attribute

I'm using mingw32-make to compile a qt project that uses opengl, it compiles correctly and everything, but it spits countless warning messages of the form:
c:/qt3/include/qcolor.h:67: warning: inline function `int qGray(int, int,
int)' declared as dllimport: attribute ignored
For this particular instance, the function declaration is:
Q_EXPORT inline int qGray( int r, int g, int b )// convert R,G,B to gray 0..255
{ return (r*11+g*16+b*5)/32; }
My question is, why is it spitting all these warning? how can I silence them without silencing other legitimate warnings (i.e. warnings that are related directly to my code and could be potential problems)?
More importantly, why is mingw ignoring the dll import attribute in the first place?
I think Qt ought to only define Q_EXPORT (Q_DECL_EXPORT in Qt 4) to be the dllexport/import attribute if one of the following macros is defined, so make sure your makefiles or code that includes Qt headers (which eventually will include qglobal.h) aren't defining any of them: WIN32, _WIN32, __WIN32__, WIN64, _WIN64, __WIN64__. Or you can just define Q_EXPORT to be nothing in your compile (or preprocessor) flags, then Qt should skip defining it.

Resources