Problem: The compiler declares a seemingly nonsensical error that a local variable in a class member function "was not declared in this scope". The code shown below is a simplified implementation of the original function, and somehow it still triggers the same error. Furthermore, the error disappears whenever I rename the variable (in each place it's used) and resumes as soon as I change the variable back to its original name ("minor"). I don't understand this behavior and can't find any information/posts on what would cause a compiler to do this. Could someone kindly offer suggestions on what might be wrong? Is it indicative of a major bug somewhere else in my code (e.g. the Matrix class definition)?
Details: I'm compiling on Linux Mint 18 using g++ on Makefiles generated by CMake. I've tried with and without a variety of compiler options (e.g. -O2, -Wall, etc.), and the result is unchanged. I've previously compiled and ran a slightly earlier version of this code/project on Windows 7 using MinGW and a self-written Makefile with no problems. I'm happy to provide additional details upon request.
Modified/minimalist code snippet from Matrix.cpp:
Matrix Matrix::BuildCofactorMatrix() const {
double minor (0.0);
minor = 1.0;
return Matrix(height_, width_);
}
Warning message:
/PATH-TO-PROJECT-ROOT/src/Matrix.cpp: In member function ‘Matrix Matrix::BuildCofactorMatrix() const’:
/PATH-TO-PROJECT-ROOT/src/Matrix.cpp:1123:5: error: ‘minor’ was not declared in this scope
minor = 1.0;
2017-08-21 Edit:
I removed unnecessary code and created a truly "Minimal, Complete, and Verifiable" example of the problem. For me, the error seems to be a function of the iostream library. If I remove the iostream inclusion, the problem seems to disappear. However, the error also depends on the c++ standard used for compiling. When I specify that g++ use, for example, -std=c++11 or -std=c++14, the problem persists, but once I remove the specification (i.e. g++ -c Matrix.cpp), the error disappears. By the way, I'm using g++ 4:5.3.1-1ubu.
Unless I'm missing something, I can't find any macros in iostream, istream, ostream, or ios that mention the term "minor", but perhaps it's further up the inclusion chain...?
Matrix.hpp:
#ifndef MATRIX_HPP
#define MATRIX_HPP
class Matrix {
public:
void BuildCofactorMatrix() const;
};
#endif
Matrix.cpp:
#include "Matrix.hpp"
#include <iostream>
void Matrix::BuildCofactorMatrix() const {
double minor (0.0);
minor = 0.0;
}
I can replicate the problem by adding #define minor(x) (x) before the function.
The macro matches minor(0.0) but not minor without the "parameter".
The line
double minor (0.0);
would be replaced by
double (0.0);
which is a valid, but useless, type cast.
So, go look for some evil macro in one of the include files.
Related
I'm having trouble with this arbitrary precision package.
I included "precisioncore.cpp", declared an int_precision, tried to compile and it told me that stdafx.h was missing.
I already read that I can simply omit this include in precisioncore.cpp, and so I did. After that it complained about memcpy not being declared in this scope, so I inlcuded .
The next error I cannot rectify:
\precisioncore.cpp|4222|error: call of overloaded 'int_precision(float_precision&)' is ambiguous|
This is line 4222: r2=(int_precision)rf;
r2 being an int_precision and rf being a float_precision. I understand that the float is explicitly casted into an int, but looking into the reference that came with the package this should not be a problem, at least not syntax-wise.
Does anyone here know this package? Any experiences with the same issue, maybe?
EDIT: It looks like the package is working perfectly in Visual Studio. Couldn't figure how to get it working in C:B, though...
ok so... I had the same problem while trying to hook up that library to CodeBlocks under GCC.
It seems to me that *int_precision(float_precision&)* constructor is not declared anywhere in *int_precision* class and that is the reason you are getting that error. So i have no clue how it can be working under Visual studio.
Anyways, my solution was to add that constructor myself:
in iprecision.h file inside *int_precision* class next to the other constructor declarations add:
int_precision( const float_precision& );
then somewhere in precisioncore.cpp file add:
int_precision::int_precision( const float_precision& s )
{//note that behavior is similar to int(double) cast
//int(9.99) yields 9; and int(-0.9) yields 0;
if(s.exponent()<0)
mNumber = ito_precision_string( int(0), true );
//code taken from int_precision(int) constructor
else
{
mNumber=s.get_mantissa();
if(mNumber[0]=='-'||mNumber[0]=='+')
mNumber.resize(s.exponent()+2);// +1.23456E2 = 123
else
mNumber.resize(s.exponent()+1);// 1.2345E2 = 123
}
}
Note that unlike other constructors this one cannot be inlined as it would create a circular header reference between iprecision.h and fprecision.h headers. That's why the implementation must be in .cpp file.
Hope this helps.
LLVM 2.1 has an option that enables warnings for "missing function prototypes." When enabled, the warning will complain about a file like this:
double square( double d )
{
return d*d;
}
void main()
{
// ...
}
The function "square" will trigger a warning because it is defined without having been declared (prototyped). You can eliminate the warning thus:
double square( double d );
double square( double d )
{
return d*d;
}
void main()
{
// ...
}
I've programmed in C++ for twenty years and I've never seen a warning like this. It does not seem useful to me.
By default, this warning is enabled in new Mac console projects (at least) in Xcode 4.1. Evidently someone found it useful enough to first implement it and then enable it by default.
Why is this a useful warning? Why does LLVM have it as an option? Why is the option enabled by default on Xcode?
The compiler uses the prototype declaration to match types for the function definition.
If you are writing the prototype in a header(interface) file and the implementation in the source file then this warning (by forcing you to provide a declaration, effectively) would prevent you from making a typo error where function definition is different than the one in declaration.
Though, without such an warning, you would get the errors while linking. One might end up wondering what the actual problem is(n number of reasons for linking errors).
The warning during compilation stage is much better indication of error than a linking error.
If could be useful to make sure every function is either visible from some header, or static.
I had cases where two files were linked together, even though none of them used the same header file.
Take this example:
int test()
{
return 0;
}
If there's no header, you can have a second file which does:
extern int test();
test();
If you are writing a library, this warning could tell you that someone could be using this function even if they were not supposed to, since this function is in no header. They should have been marked as static.
Prototype of "int test()" should be "int test(void)" then it's OK.
I have a c++ file that keeps throwing errors about four files up the chain, while every other file using that #include compiles fine.
It keeps giving me this kind of stuff. I am certain the include file is fine as 1. All of the others which use this same file compile fine and 2. I looked at the file, and it is fine.
/usr/include/opal/opal/mediafmt.h:305:9: error: expected identifier before numeric constant
/usr/include/opal/opal/mediafmt.h:305:9: error: expected ‘}’ before numeric constant
/usr/include/opal/opal/mediafmt.h:305:9: error: expected unqualified-id before numeric constant
/usr/include/opal/opal/mediafmt.h:308:14: error: bit-field ‘mode’ with non-integral type
It's odd because it throws the error about 5 files up the chain:
In file included from /usr/include/opal/opal/connection.h:44:0,
from /usr/include/opal/opal/call.h:41,
from /usr/include/opal/opal/manager.h:42,
from /usr/include/opal/opal/endpoint.h:41,
from /usr/include/opal/opal/localep.h:41,
from /home/jonathan/workspace/HHPVideoServer/opal/GstEndPoint.h:12,
from /home/jonathan/workspace/HHPVideoServer/opal/opal-call-manager.h:42,
from ../gui/HHPVideoCodecGui.cc:3:
I checked to make sure I wasn't screwing up any #define s but that was the only idea I had. Is there a good approach someone can offer me on how to track this error down?
Here is the file:
http://www.opalvoip.org/docs/opal-v3_9/da/d60/mediafmt_8h-source.html
Update
Here is the struct with the troublesome line from the preprocessor. I suppose the "0L" is the trouble.
struct H245GenericInfo {
H245GenericInfo() { memset(this, 0, sizeof(*this)); }
unsigned ordinal:16;
enum Modes {
0L,
Collapsing,
NonCollapsing
} mode:3;
enum IntegerTypes {
UnsignedInt,
Unsigned32,
BooleanArray
} integerType:3;
bool excludeTCS:1;
bool excludeOLC:1;
bool excludeReqMode:1;
};
then
#define None 0L
from "/usr/include/X11/X.h" causes 0L to be substituted for None in the Modes enumeration at line 305.
from the X11 lib. The reason the other files were compiling is that they weren't also using Gtk. Does any one have a work around that doesn't involve me rewriting either of the lib files?
solution
I just put the offending #include above everything else. Thanks for the help everyone.
Assuming you're using gcc, run gcc -E your-file.c > tmpfile. This runs just the preprocessor. The output is going to be quite voluminous, but it should help you track down the problem.
What does line 305 look like?
EDIT:
Given your update, yes, the problem is that "None" is being defined as a macro before your mediafmt.h tries to define it as an enumerator. Can you add #undef None after including X.h and before including mediafmt.h? (If so, be sure to comment it.)
EDIT2: Rearranging the #include directives might be a better solution -- but again, be sure to add a comment explaining the reason.
Because you said that this include works from other files, I'm guessing that the order of your #includes may be different in the failing file. Try moving the #include for opal-call-manager.h to the top of the file.
Ideally, you would follow the answers others have posted to track down the root cause, but simply reordering the #includes may be a quick solution and will help narrow down what is conflicting.
Since you found 0L in place of None it's likely you have #define None 0L somewhere in your include chain. Either reorder the includes, like Klox suggested, so this definition happens after mediafmt.h is included, or try and convert, undefine, or fix the offending None definition elsewhere.
I have a header file with some inline template methods. I added a class declaration to it (just a couple of static methods...it's more of a namespace than a class), and I started getting this compilation error, in a file that uses that new class.
There are several other files that include the same .h file that still compile without complaint.
Googling for the error gives me a bunch of links to mailing lists about bugs on projects that have a similar error message (the only difference seeming to be what the constructor, destructor, or type conversion is supposed to precede).
I'm about ready to start stripping everything else away until I have a bare-bones minimal sample so I can ask the question intelligently, but I figured I'd take a stab at asking it the stupid way first:
Can anyone give me a basic clue about what this error message actually means so I might be able to begin to track it down/google it?
Just for the sake of completeness, the first example of where I'm seeing this looks more or less like
namespace Utilities
{
template <typename T> GLfloat inline NormalizeHorizontally(T x)
{
GLfloat scaledUp = x*2.0;
GLfloat result = scaledUp / Global::Geometry::ExpectedResolutionX;
return result;
}
}
It means that you put the "inline" keyword in the wrong place. It needs to go before the method's return type, e.g.
template <typename T> inline GLfloat NormalizeHorizontally(T x)
Simple as that.
The reason that you got this message on one compilation unit and not others may be because it is a templated function that was not being instantiated from those other compilation units.
Generally, if you get an "expected blah blah before foobar" error, this is a parsing error and it often indicates a simple syntax mistake such as a missing semicolon, missing brace, or misordered keywords. The problem is usually somewhere around the portion mentioned, but could actually be a while back, so sometimes you have to hunt for it.
I'm consistently running into an internal compiler error while attempting to switch from MSVC6 to MSVC 2008. After much work commenting out different parts of the program, I've traced the error to two lines of code in two different CPP files. Both of these CPP files compile successfully, yet somehow have an effect on whether or not the error manifests in other files.
Both of those lines involve instantianting several complex, nested templates. They also appear to be the only places in the app that use an abstract class as one of the template parameters. That said, I'm far from certain that the issue involves either abstract classes or templates, it's just the most obvious thing I've noticed. I can't even be sure that these lines are significant at all. Here's what they look like, though:
m_phDSAttributes = new SObjDict<RWCString, SIDataSource>(&RWCString::hash);
So we've got SObjDict, a templatized dictionary class, SIDataSource, an abstract interface, and the parameter is a pointer to a static member function of RWCString.
I've been playing around with the code some, and I can occasionally get the error to move from one CPP file to another (for instance, I changed a bunch of template declarations from using class to typename), but I can't find any rhyme or reason to it.
I'm at a loss as to how to debug this issue further. The exact error output by the compiler (with the name of my source file changed) is below. There is no mention of it anywhere on the internet. I'm pretty desperate for any advice on how to proceed. I don't expect someone to say "oh, you just need to do XYZ", but a pointer on how to debug this sort of issue would be greatly appreciated.
1>d:\Dev\webapi.cpp : fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c', line 5905)
The trick seems to be disabling precompiled headers. I have no idea why that solves the problem, and it's very unfortunate since my build time for the affected project has gone from less than 30 secs to nearly 5 minutes, but at least I can progress forward.
It's a reasonable bet to assume that p2symtab.c is (part of) the symbol table code. This would immediately explain how the upgrade caused it; this code has been rewritten. (Remember the 255 character length warnings of VC6?)
In this case, there is no new entry in the symbol table, so it's likely a lookup in the symbol table failing spectactularly. It would be interesting to see if the context in which th name lookup happens affects the result. For instance, what happens if you change the code to
typedef SObjDict<RWCString, SIDataSource> SObjDict_RWCString_SIDataSource;
m_phDSAttributes = new SObjDict_RWCString_SIDataSource(&RWCString::hash);
This will force another symbol table entry to be created, for SObjDict_RWCString_SIDataSource. This entry is sort of a symbolic link to the template instantiation. The new name can (and must) be looked up on its own.
Start breaking it down into smaller parts. My first guess is the pointer to the static function is going to be the problem. Can you make a dummy non-template class with the same parameter in the constructor? Does it compile if you don't use an abstract class in the template?
Looks like I'm sending you in the wrong direction, the following compiles fine in 2008:
class thing {
public:
static void hash( short sht ) {
}
void hash( long lng ) {
}
};
class thing2 {
public:
thing2( void (short ) ){}
};
int _tmain(int argc, _TCHAR* argv[])
{
thing2* t = new thing2( &thing::hash );
delete t;
return 0;
}
The principle remains though, remove/replace complex elements until you have code that compiles and you'll know what is causing the problem.
fatal error C1001: An internal error has occurred in the compiler.
1>(compiler file 'f:\dd\vctools\compiler\utc\src\p2\p2symtab.c
i also observed the same error when i try to build my vs 2005 code to vs 2008. but it happen till i have not installed Service pack of VS 2008...
have you installed Service pack... i think this will resolved your issue....
This typically happens with template instantiation. Unfortunately it could be caused by many things, but 99% of the time your code is subtly invoking undefined behavior.