0

I have an existing C++ and Qt program that builds fine under MSVC but fails to build with MinGW.

Under MinGW I get lots of syntax errors such as:

Redefinition of 'QString foobar'

I have extracted the issue into a minimum working example:

//main.cpp
#include <QString>
#include <iostream>

using namespace std;

class MyClass {

public:
    MyClass(const QString &foo, const QString &bar, const QString baz)
        : foo_(foo), bar_(bar), baz_(baz) {}

    QString foo_;
    QString bar_;
    QString baz_;
};

int main(int argc, char **argv) {

    QString foo = QString("foo");
    QString bar = QString("bar");
    QString baz = QString("baz");

    MyClass my(foo, bar, baz);

    QString a = QString(foo);
    QString b = QString(bar);
    QString c = QString(baz);

    MyClass my2(a,b,c);
    MyClass my3(QString(foo), QString(bar), QString(baz));
    //MyClass my4(QString(foo), QString(bar), QString(foo)); //redefinition error

    return 0;
}

Which gives the error:

main.cpp:31: error: C2086: 'QString foo' : redefinition

As pointed out in the comments my problem is being caused by a parse issue that is called "most vexing parse". With this knowledge I have refined my issue further and found the following difference between MSVC and MinGW. The following line of code compile under MSVC2013 but not under MinGW:

MyClass my5(QString(foo), QString(bar), QString(foo), Foo::Foobar(5));

It seems that adding "Foo::Foobar(5)" causes MSVC to see this line as a variable declaration, but MinGW still sees this as function declaration.

My question is, can I work around this issue through some compile flag in GCC, or must I refactor my whole project to avoid the most vexing parse issue all together.

lanoxx
  • 12,249
  • 13
  • 87
  • 142
  • Stupid question: QT only includes libraries for MinGW 32Bit, and you target 64bits. Did you solve this issue? – Adrian Maire Feb 22 '17 at 12:35
  • 1
    You should try to strip down that program and produce a mcve: http://stackoverflow.com/help/mcve – The Quantum Physicist Feb 22 '17 at 12:37
  • You need to show us the code. Chances are your code is invalid and MSVC is just not as strict as GCC. – rubenvb Feb 22 '17 at 12:38
  • 1
    Maybe a leftover of msvc-build? Set the build and run directory different from the msvc build directories or delete them before. – Sebastian Lange Feb 22 '17 at 13:32
  • Could you give more code context to what fails ? This is very likely like @rubenvb said, GCC is more strict than MSVC. – Adrien Leravat Feb 22 '17 at 14:57
  • @lanoxx I'm having trouble understanding why you have to have a class to show the problem... will `int main() { std::cout< – The Quantum Physicist Feb 23 '17 at 08:37
  • @TheQuantumPhysicist That works, but thats not my issue, there is some problem due to the use of the QString constructor when using in the constructor of MyClass. Note that my3 works by my4 produces an error. – lanoxx Feb 23 '17 at 09:48
  • 1
    I can reproduce this with gcc. The warning/advice from clang is: "`Parentheses were disambiguated as a function declaration [-Wvexing-parse]`". Adding parentheses around the arguments (like `my4((QString(foo)), (QString(bar)), (QString(foo)));`) removes the warning and makes it compile – Karsten Koop Feb 23 '17 at 09:49
  • 1
    [Wikipedia has something about this](https://en.wikipedia.org/wiki/Most_vexing_parse) – Karsten Koop Feb 23 '17 at 09:52
  • Can I somehow configure the compiler to work around this until I can refactor the code? – lanoxx Feb 23 '17 at 10:05
  • @lanoxx while you successfully recognized this as "the most vexing parse", I recommend in the future to show very, very simple examples when you want describe the problem. You should keep trimming down your example further until you identify the problem with a specific line when inserted. Thanks Karsten, but not all people would be insterested in recreating the problem on their computer. Good luck! – The Quantum Physicist Feb 23 '17 at 11:17

1 Answers1

2

This code would be a function declaration:

MyClass my4(QString(foo), QString(bar), QString(foo));

because it matches the grammar specification for a function. Look up "most vexing parse" for more information. The error is because a function declaration cannot have two parameters with the same identifier. Whenever a statement starts off with T name( U( , this is possible

The error with MyClass my4(QString(foo), QString(bar), QString(foo), Foo::Foobar(5)); could be a gcc compiler bug, it reminds me of this similar issue.

To avoid this problem in this case, avoid redundant casts:

MyClass my4(foo, bar, foo);

Or you could get in the habit of using list initialization:

MyClass my4{ foo, bar, foo };

Note, you had several redundant casts earlier in the code too; e.g. QString foo = QString("foo"); could be QString foo("foo");; similarly with a, b, c.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365