Compilation errors C2589, C2062, C2059, C2988, C2143
-
My program had been compiling with no problems, but now I started to get several errors when I try to compile.
I'm using Windows 10, Qt 5.15, Qt Creator 8.0.1, MSVC 2019Here's the list of errors (in Portuguese, sorry):
All the errors make reference to the same file, exprtk.hpp, which wasn't created by me. However, I haven't modified this file and it it used to compile correctly.
I've seen somewhere that errors like this can be due to conflicts between <cmath> and <math.h>. I notice this file contains
#include <cmath>
in its header. I've tried to change it to <math.h> but the errors persisted.My last modifications in the project after the last time it compiled correctly were very basic ones. I've just created some new classes, all of them derived from QWidget and QObject, and they make no reference to the exprtk.hpp file.
I've also tried to delete the .pro.user files, rename the project folder and change the build location. Nothing works.
I've read it could be a failure of MSVC, but I have no clue what else I can try.
Any suggestions?
-
@Linhares
As @jsulm says.
If you have just made some alterations and it no longer works, try backing out of the alterations till you identify which one causes it.
Assuming that something somewhere includesexprtk.hpp
(presumably your project includes this somewhere, else it wouldn't be involved in the compilation), even if indirectly through including something else, look at any includes immediately before it gets included. Introducing, say, a Qt include before it gets included could have definitions which interfere with its behaviour. I usually try to put any external includes as the first thing before any other includes. -
Ok, I've narrowed down the issue.
@jsulm, the file that causes the errors (
exprtk.hpp
) is a very big one (over 40k lines). Here's the includes section:#include <algorithm> #include <cassert> #include <cctype> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <deque> #include <exception> #include <functional> #include <iterator> #include <limits> #include <list> #include <map> #include <set> #include <stack> #include <stdexcept> #include <string> #include <utility> #include <vector>
This is the part that causes the first 3 errors:
struct ilesscompare { inline bool operator() (const std::string& s1, const std::string& s2) const { const std::size_t length = std::min(s1.size(),s2.size()); for (std::size_t i = 0; i < length; ++i) { const char_t c1 = static_cast<char_t>(std::tolower(s1[i])); const char_t c2 = static_cast<char_t>(std::tolower(s2[i])); if (c1 > c2) return false; else if (c1 < c2) return true; } return s1.size() < s2.size(); } };
The errors are caused specifically by this line:
const std::size_t length = std::min(s1.size(),s2.size());
And the errors are:
error: C2589: '(': invalid token in the right side of '::' error: C2062: unexpected 'unknown-type' type error: C2059: syntax error: ')'
As per @JonB's suggestion, I started to back out the alterations. In fact, the
exprtk.hpp
file is included in a file namedExpressionEvaluatorThread.h
. Here's the include section:#include "ExpressionEvaluator/exprtk.hpp" #include <cstdio> #include <QObject> #include <QThread> #include <QQueue> #include "utils.h" #include <QMutex>
I've already tried to change the order of the includes, but the error persists anyway.
What makes me puzzled is that these particular files (ExpressionEvaluatorThread.h
andexprtk.hpp
) have not been changed in my last alterations. I don't know how it's possible that it started to trigger errors if it was working correctly before.Any suggestions?
-
@Linhares said in Compilation errors C2589, C2062, C2059, C2988, C2143:
const std::size_t length = std::min(s1.size(),s2.size());
error: C2589: '(': invalid token in the right side of '::'
So this should be the
(
of thestd::min(
.This is only a thought. Over the years various bits of C/C++ have done a
#define min(...
macro (and same formax()
). If the error occurs specifically onmin()
(e.g. the line got paststd::size_t
), and I got an "invalid token" message, I would wonder whether something might have done such a#define
....Is your
#include "ExpressionEvaluator/exprtk.hpp"
really the very first line/#include
in the file? Do you fancy setting up a test project/file which just has#include "ExpressionEvaluator/exprtk.hpp"
in it to see whether that compiles?As for what has changed to make this start happening, you may not discover that until after you have tracked down the issue....
-
@JonB your idea was great.
I tried to add
#include "ExpressionEvaluator/exprtk.hpp"
to a new project and it compiled correctly.
Then I tried to add it directly to themain.cpp
of my project and it compiled as well.
So I started to add#include "ExpressionEvaluator/exprtk.hpp"
to each object on the way down the hierarchy of objects. I found a particular object that includes a class that has a very deep level child that has this:extern C { #include <windows.h> }
My code compiles if I add
#include "ExpressionEvaluator/exprtk.hpp"
before that, but it doesn't if I add it after that.
So that's where the issue begins.The problem is that I can't easily move the
#include "ExpressionEvaluator/exprtk.hpp"
to an upper level in the structure of my code, so it wouldn't be an easy task to reorganize everything to make it appear earlier than#include <windows.h>
.
Is there a way so I could "deactivate" the effects of#include <windows.h>
outside of the class that uses it? -
@Linhares said in Compilation errors C2589, C2062, C2059, C2988, C2143:
Is there a way so I could "deactivate" the effects of
#include <windows.h>
outside of the class that uses it?The sad thing is it sounds like you are including
windows.h
in your code everywhere? That's a shame, partly because if possible Qt should isolate your code from it and partly I imagine it adds a lot to compilation time.Go find where it
#define
smin()
. ISTR it's likely to be in some#ifdef
which lets you switch it off? Or, after you have included it try a#undef min
? If I understand right, you could put that in your code just after#include "ExpressionEvaluator/exprtk.hpp"
? You may find this is a Googlabble issue, there will be others with problems if it definesmin
/max
. -
When using windows headers you should add NOMINMAX so that the headers don't define
min
andmax
as macros. -
I managed to solve it by moving an
#include
(of the class that has the#include "ExpressionEvaluator/exprtk.hpp"
in it) that was in a .cpp file to the .h file and putting it before the#include
of the class that has the#include <windows.h>
in it.
Thanks everyone for the help.