2

I am new to Qt and I am trying to run basic gstreamermm example with Qt. When I include gstreamermm.h in main.cpp of qt, I get compilation error. I can not understand what does that error says. I am using Qt creator for this example.

#include <QApplication>
#include <gstreamermm.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

I get following compilation error

g++ -c -pipe -g -pthread -Wall -W -D_REENTRANT -fPIE -DQT_QML_DEBUG -DQT_DECLARATIVE_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I../../../../Qt5.1.0/5.1.0/gcc_64/mkspecs/linux-g++ -I../PlayerBasic -I/usr/include/giomm-2.4 -I/usr/lib/x86_64-linux-gnu/giomm-2.4/include -I/usr/include/gstreamer-0.10 -I/usr/include/glibmm-2.4 -I/usr/lib/x86_64-linux-gnu/glibmm-2.4/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/sigc++-2.0 -I/usr/lib/x86_64-linux-gnu/sigc++-2.0/include -I/usr/include/libxml2 -I/usr/include/gstreamermm-0.10 -I/usr/lib/gstreamermm-0.10/include -I/usr/include/libxml++-2.6 -I/usr/lib/libxml++-2.6/include -I../../../../Qt5.1.0/5.1.0/gcc_64/include -I../../../../Qt5.1.0/5.1.0/gcc_64/include/QtWidgets -I../../../../Qt5.1.0/5.1.0/gcc_64/include/QtGui -I../../../../Qt5.1.0/5.1.0/gcc_64/include/QtCore -I. -I. -I. -o main.o ../PlayerBasic/main.cpp
In file included from /usr/include/glibmm-2.4/glibmm.h:92:0,
                 from /usr/include/gstreamermm-0.10/gstreamermm/bin.h:7,
                 from /usr/include/gstreamermm-0.10/gstreamermm.h:65,
                 from ../PlayerBasic/main.cpp:3:
/usr/include/glibmm-2.4/glibmm/balancedtree.h:225:40: error: macro "Q_FOREACH" requires 2 arguments, but only 1 given
In file included from /usr/include/gstreamermm-0.10/gstreamermm/query.h:30:0,
                 from /usr/include/gstreamermm-0.10/gstreamermm/message.h:33,
                 from /usr/include/gstreamermm-0.10/gstreamermm/element.h:34,
                 from /usr/include/gstreamermm-0.10/gstreamermm/bin.h:28,
                 from /usr/include/gstreamermm-0.10/gstreamermm.h:65,
                 from ../PlayerBasic/main.cpp:3:
/usr/include/gstreamermm-0.10/gstreamermm/structure.h:358:39: error: macro "Q_FOREACH" requires 2 arguments, but only 1 given
In file included from /usr/include/gstreamermm-0.10/gstreamermm.h:67:0,
                 from ../PlayerBasic/main.cpp:3:
/usr/include/gstreamermm-0.10/gstreamermm/bufferlist.h:189:39: error: macro "Q_FOREACH" requires 2 arguments, but only 1 given
In file included from /usr/include/gstreamermm-0.10/gstreamermm.h:98:0,
                 from ../PlayerBasic/main.cpp:3:
/usr/include/gstreamermm-0.10/gstreamermm/taglist.h:597:39: error: macro "Q_FOREACH" requires 2 arguments, but only 1 given
In file included from /usr/include/sigc++-2.0/sigc++/signal.h:8:0,
                 from /usr/include/sigc++-2.0/sigc++/sigc++.h:80,
                 from /usr/include/glibmm-2.4/glibmm/thread.h:58,
                 from /usr/include/glibmm-2.4/glibmm.h:87,
                 from /usr/include/gstreamermm-0.10/gstreamermm/bin.h:7,
                 from /usr/include/gstreamermm-0.10/gstreamermm.h:65,
                 from ../PlayerBasic/main.cpp:3:
/usr/include/sigc++-2.0/sigc++/signal_base.h: In constructor 'sigc::internal::temp_slot_list::temp_slot_list(sigc::internal::temp_slot_list::slot_list&)':
/usr/include/sigc++-2.0/sigc++/signal_base.h:181:50: error: value-initialization of reference type 'sigc::internal::temp_slot_list::slot_list& {aka std::list<sigc::slot_base>&}'
In file included from /usr/include/sigc++-2.0/sigc++/sigc++.h:80:0,
                 from /usr/include/glibmm-2.4/glibmm/thread.h:58,
                 from /usr/include/glibmm-2.4/glibmm.h:87,
                 from /usr/include/gstreamermm-0.10/gstreamermm/bin.h:7,
                 from /usr/include/gstreamermm-0.10/gstreamermm.h:65,
                 from ../PlayerBasic/main.cpp:3:
/usr/include/sigc++-2.0/sigc++/signal.h: At global scope:
/usr/include/sigc++-2.0/sigc++/signal.h:617:44: error: ISO C++ forbids declaration of 'result_type' with no type [-fpermissive]
/usr/include/sigc++-2.0/sigc++/signal.h:630:5: error: 'static int sigc::internal::signal_emit0<T_return, T_accumulator>::result_type(sigc::internal::signal_impl*)' conflicts with a previous declaration
/usr/include/sigc++-2.0/sigc++/signal.h:598:47: note: previous declaration 'typedef typename T_accumulator::result_type sigc::internal::signal_emit0<T_return, T_accumulator>::result_type'
/usr/include/sigc++-2.0/sigc++/signal.h: In static member function 'static int sigc::internal::signal_emit0<T_return, T_accumulator>::result_type(sigc::internal::signal_impl*)':
/usr/include/sigc++-2.0/sigc++/signal.h:628:48: error: expected primary-expression before '(' token
/usr/include/sigc++-2.0/sigc++/signal.h:628:54: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h:629:48: error: expected primary-expression before '(' token
/usr/include/sigc++-2.0/sigc++/signal.h:629:54: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h: In static member function 'static sigc::internal::signal_emit0<T_return, T_accumulator>::result_type sigc::internal::signal_emit0<T_return, T_accumulator>::emit_reverse(sigc::internal::signal_impl*)':
/usr/include/sigc++-2.0/sigc++/signal.h:647:56: error: expected primary-expression before '(' token
/usr/include/sigc++-2.0/sigc++/signal.h:647:62: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h:648:56: error: expected primary-expression before '(' token
/usr/include/sigc++-2.0/sigc++/signal.h:648:62: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h: At global scope:
/usr/include/sigc++-2.0/sigc++/signal.h:672:44: error: ISO C++ forbids declaration of 'result_type' with no type [-fpermissive]
In file included from /usr/include/sigc++-2.0/sigc++/sigc++.h:80:0,
                 from /usr/include/glibmm-2.4/glibmm/thread.h:58,
                 from /usr/include/glibmm-2.4/glibmm.h:87,
                 from /usr/include/gstreamermm-0.10/gstreamermm/bin.h:7,
                 from /usr/include/gstreamermm-0.10/gstreamermm.h:65,
                 from ../PlayerBasic/main.cpp:3:
/usr/include/sigc++-2.0/sigc++/signal.h:701:5: error: 'static int sigc::internal::signal_emit0<T_return, sigc::nil>::result_type(sigc::internal::signal_impl*)' conflicts with a previous declaration
In file included from /usr/include/sigc++-2.0/sigc++/sigc++.h:80:0,
                 from /usr/include/glibmm-2.4/glibmm/thread.h:58,
                 from /usr/include/glibmm-2.4/glibmm.h:87,
                 from /usr/include/gstreamermm-0.10/gstreamermm/bin.h:7,
                 from /usr/include/gstreamermm-0.10/gstreamermm.h:65,
                 from ../PlayerBasic/main.cpp:3:
/usr/include/sigc++-2.0/sigc++/signal.h:661:20: note: previous declaration 'typedef T_return sigc::internal::signal_emit0<T_return, sigc::nil>::result_type'
/usr/include/sigc++-2.0/sigc++/signal.h: In static member function 'static int sigc::internal::signal_emit0<T_return, sigc::nil>::result_type(sigc::internal::signal_impl*)':
/usr/include/sigc++-2.0/sigc++/signal.h:684:33: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h:685:27: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h:688:24: error: expected primary-expression before '.' token
In file included from /usr/include/sigc++-2.0/sigc++/sigc++.h:80:0,
                 from /usr/include/glibmm-2.4/glibmm/thread.h:58,
                 from /usr/include/glibmm-2.4/glibmm.h:87,
                 from /usr/include/gstreamermm-0.10/gstreamermm/bin.h:7,
                 from /usr/include/gstreamermm-0.10/gstreamermm.h:65,
                 from ../PlayerBasic/main.cpp:3:
/usr/include/sigc++-2.0/sigc++/signal.h:692:31: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h: In static member function 'static sigc::internal::signal_emit0<T_return, sigc::nil>::result_type sigc::internal::signal_emit0<T_return, sigc::nil>::emit_reverse(sigc::internal::signal_impl*)':
/usr/include/sigc++-2.0/sigc++/signal.h:728:39: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h:729:43: error: expected primary-expression before '(' token
/usr/include/sigc++-2.0/sigc++/signal.h:729:49: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h:732:40: error: expected primary-expression before '(' token
/usr/include/sigc++-2.0/sigc++/signal.h:732:46: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h:736:47: error: expected primary-expression before '(' token
/usr/include/sigc++-2.0/sigc++/signal.h:736:53: error: expected primary-expression before '.' token
/usr/include/sigc++-2.0/sigc++/signal.h: At global scope:
/usr/include/sigc++-2.0/sigc++/signal.h:766:38: error: expected ')' before '*' token
In file included from /usr/include/glibmm-2.4/glibmm/value_custom.h:32:0,
                 from /usr/include/glibmm-2.4/glibmm/value.h:196,
                 from /usr/include/glibmm-2.4/glibmm/propertyproxy_base.h:25,
                 from /usr/include/glibmm-2.4/glibmm/propertyproxy.h:25,
                 from /usr/include/glibmm-2.4/glibmm/objectbase.h:24,
                 from /usr/include/glibmm-2.4/glibmm/wrap.h:26,
                 from /usr/include/glibmm-2.4/glibmm/containerhandle_shared.h:25,
                 from /usr/include/glibmm-2.4/glibmm/arrayhandle.h:23,
                 from /usr/include/glibmm-2.4/glibmm.h:91,
                 from /usr/include/gstreamermm-0.10/gstreamermm/bin.h:7,
                 from /usr/include/gstreamermm-0.10/gstreamermm.h:65,
                 from ../PlayerBasic/main.cpp:3:
/usr/include/c++/4.7/typeinfo:41:37: error: expected '}' before end of line
/usr/include/c++/4.7/typeinfo:41:37: error: expected unqualified-id before end of line
/usr/include/c++/4.7/typeinfo:41:37: error: expected '}' before end of line
/usr/include/c++/4.7/typeinfo:41:37: error: expected '}' before end of line
/usr/include/c++/4.7/typeinfo:41:37: error: expected declaration before end of line
make: *** [main.o] Error 1

Any help regarding above is really appreciated.

sap
  • 75
  • 1
  • 1
  • 10

1 Answers1

5

The error appears because Qt defines foreach macro as a shorthand for Q_FOREACH. This conflicts with declaration of foreach method in a few gstreamermm classes.

There are a few possible ways to avoid the problem:

  1. Add CONFIG += no_keywords line to your Qt project file. Note that then you won't be able to use Qt-specific keywords like e.g. signals and slots. If you use them already (e.g. because they were auto-generated by QtCreator), you can replace them with Q_SIGNALS and Q_SLOTS macros.

  2. Change the order of header inclusion by putting gstreamermm.h before Qt headers.

  3. Put #undef foreach after including Qt headers but before including gstreamermm.h.

2 and 3 are much less elegant solutions, since the order of header inclusion shouldn't matter in a well-written application which uses well-written libraries and one should not introduce any #defines or #undefines which would affect the included declarations unless explicitly specified by the documentation of the used libraries.

Michał Wróbel
  • 684
  • 4
  • 10
  • Now I get following compilation error In file included from ../untitled/main.cpp:1:0: ../untitled/mainwindow.h:18:9: error: expected ':' before 'slots' ../untitled/mainwindow.h:18:9: error: 'slots' does not name a type make: *** [main.o] Error 1 – sap Aug 25 '13 at 17:38
  • 1
    You're right - `no_keywords` can break your existing code. To avoid this, change `slots` to `Q_SLOTS`. I've updated the answer to include this remark. – Michał Wróbel Aug 26 '13 at 07:11
  • That worked!! Thanks. But I cannot really understand what was the problem? – sap Aug 27 '13 at 01:24
  • 1
    Qt framework realizes some of the idioms it provides (like signals and slots pattern, iteration over containers, etc. both for user's and Qt's own internal use) as C preprocessor macros like `Q_SIGNALS`, `Q_SLOTS`, `Q_FOREACH`, etc. However, to make the code look nicer as if these features were built into the language, Qt also defines "shortcut" macros like `signals`, `slots`, `foreach` respectively. Even though they look like true keywords (`if`, `for`, `while`, etc.) they are only C preprocessor macros. – Michał Wróbel Aug 27 '13 at 17:34
  • 3
    Unlike `Q_*` macros, tokens like `signals`, `slots`, `foreach` are likely to appear in other (non-Qt) code as identifiers (variable, functions, class, method names, etc.) which leads to a conflict. This was the case with `gstreamermm` library. E.g. in `/usr/include/glibmm-2.4/glibmm/balancedtree.h`), class `BalancedTree` contains a declaration of method `foreach`. However, before even this token reaches the C++ compiler where it would be properly interpreted as a method declaraton, C preprocessor, having a definition of a macro `foreach` to expand to `Q_FOREACH`, performed such a substitution. – Michał Wróbel Aug 27 '13 at 17:40
  • 1
    Then the C preprocessor identified that `Q_FOREACH` is another macro and tried to expand it. However, `Q_FOREACH` (defined in `/usr/include/Qt/qglobal.h`) is a macro which takes two parameters: `variable` and `container`. Since the original declaration of `foreach` method had a single argument (i.e. no commas in the parentheses), the C preprocessor failed to substitute the `Q_FOREACH` macro and thus failed with an error. If the `foreach` method declaration had two arguments, the substitution would succeed, but the most probably the compilation would fail. – Michał Wróbel Aug 27 '13 at 17:53
  • 1
    `no_keywords` in the Qt project file avoids to declare the `signals`, `slots` and `foreach` (and maybe some other) macros. However, then you need to use the original long versions of the macros in your code. – Michał Wróbel Aug 27 '13 at 17:55
  • 1
    C preprocessor macros are evaluated in order, i.e. a macro definition applies from the point where it was `#define`d up to the place it is `#undef`ined (if there is one). Since the `foreach` macro is defined inside Qt headers, including `gstreamermm.h` before the Qt headers avoids the problem. However, it is not a nice an elegant solution because: 1. You won't be able to use GStreamer's `foreach` methods in your code 2. in a properly written program and headers, the order of header inclusion shouldn't matter (i.e. one should be able to freely change the order of headers with breaking anything) – Michał Wróbel Aug 27 '13 at 18:14
  • 1
    There is one more way to do it. You can `#undef` the macros which get in the way i.e. put `#undef foreach` before including `gstreamermm.h`... – Michał Wróbel Aug 27 '13 at 18:16
  • Thanks a lot of explaining in detail. That cleared my doubts. I really appreciate it!! – sap Aug 27 '13 at 23:12