I came across this error when running make on a large project using gcc5.4.0.
/usr/include/c++/5/sstream:300:14: error: '__xfer_bufptrs' redeclared with 'public' access
struct __xfer_bufptrs
^
/usr/include/c++/5/sstream:67:14: note: previously declared 'private' here
struct __xfer_bufptrs;
To me it seems like an issue with the compiler? Since the issue arises in a standard c++ library sstream? It does not make sense to me, am I using a wrong compiler?
Here are the code snippets the error messages refer to:
1.) sstream starting at line 67
class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
{
struct __xfer_bufptrs;
public:
2.) sstream at line 300
#if _GLIBCXX_USE_CXX11_ABI
// This type captures the state of the gptr / pptr pointers as offsets
// so they can be restored in another object after moving the string.
struct __xfer_bufptrs
{
__xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to)
: _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1}
{
I know there cannot be anything wrong with the standard library so why is it throwing an error?
This is the closest I got to some answer:
https://github.com/PacificBiosciences/pbbam/issues/14
And it seems the answer revolves around these "Dprivate" and "Dpublic" flags. Which I assume are compiler flags, but I'm not sure what they do.
Although the thread at github hits the spot, it seems to miss the reason. You most likely are building some unit or other tests in your project that redefine the 'private' keyword like so:
#define private public
Or do the respective thing via command like (-Dprivate=public). This is a commonly used practice to expose private members for testing without making the tested code dependent on the testing code.
However look at your snippets. The first one declares __xfer_bufptrs as private regardless of your definition of private. Next second snippet is surely (haven't checked though) in an explicit private block. Now if your definition of private is in place you will ned up with public in the second snippet which is a fault.
You have at least two options, other are surely also possible:
You #undef the private definition before including system headers and define again after inclusion of those, or
You use another macro to define your own private/public sections e.g.: #define my_public public which can be redefined at will. This solution seems icky though ;)
Oh and for the future in your own code always use explicit access qualification to avoid this sort of mess at least with your own code :)
Related
I am trying to find all places in a large and old code base where certain constructors or functions are called. Specifically, these are certain constructors and member functions in the std::string class (that is, basic_string<char>). For example, suppose there is a line of code:
std::string foo(fiddle->faddle(k, 9).snark);
In this example, it is not obvious looking at this that snark may be a char *, which is what I'm interested in.
Attempts To Solve This So Far
I've looked into some of the dump features of gcc, and generated some of them, but I haven't been able to find any that tell me that the given line of code will generate a call to the string constructor taking a const char *. I've also compiled some code with -s to save the generated equivalent assembly code. But this suffers from two things: the function names are "mangled," so it's impossible to know what is being called in C++ terms; and there are no line numbers of any sort, so even finding the equivalent place in the source file would be tough.
Motivation and Background
In my project, we're porting a large, old code base from HP-UX (and their aCC C++ compiler) to RedHat Linux and gcc/g++ v.4.8.5. The HP tool chain allowed one to initialize a string with a NULL pointer, treating it as an empty string. The Gnu tools' generated code fails with some flavor of a null dereference error. So we need to find all of the potential cases of this, and remedy them. (For example, by adding code to check for NULL and using a pointer to a "" string instead.)
So if anyone out there has had to deal with the base problem and can offer other suggestions, those, too, would be welcomed.
Have you considered using static analysis?
Clang has one called clang analyzer that is extensible.
You can write a custom plugin that checks for this particular behavior by implementing a clang ast visitor that looks for string variable declarations and checks for setting it to null.
There is a manual for that here.
See also: https://github.com/facebook/facebook-clang-plugins/blob/master/analyzer/DanglingDelegateFactFinder.cpp
First I'd create a header like this:
#include <string>
class dbg_string : public std::string {
public:
using std::string::string;
dbg_string(const char*) = delete;
};
#define string dbg_string
Then modify your makefile and add "-include dbg_string.h" to cflags to force include on each source file without modification.
You could also check how is NULL defined on your platform and add specific overload for it (eg. dbg_string(int)).
You can try CppDepend and its CQLinq a powerful code query language to detect where some contructors/methods/fields/types are used.
from m in Methods where m.IsUsing ("CClassView.CClassView()") select new { m, m.NbLinesOfCode }
I'm creating a simple game in SDL2 and learning about C++ classes, however I'm having difficulty with private variables and class constructors. I'm attempting to access an SDL_Texture that is defined as a private variable and modify it within the constructor.
Upon compilation the code below causes the following error:
In constructor 'PlayerShip::PlayerShip(SDL_Texture*)':
|5| error: 'ShipSprite' was not declared in this scope
Header file (PlayerShip.h):
#ifndef PLAYERSHIP_H
#define PLAYERSHIP_H
#include "SDL2/SDL.h"
class PlayerShip
{
public:
PlayerShip(SDL_Texture * tex);
private:
SDL_Texture * ShipSprite = nullptr; //The variable/texture I want to modify
};
#endif
CPP file (PlayerShip.cpp)
#include "PlayerShip.h"
PlayerShip::PlayerShip(SDL_Texture * tex) //ctor
{
ShipSprite = tex; //This needs to change the private variable above. However "ShipSprite" is apparently not in scope.
}
It is defined in the header, however I'm not sure why it won't access it even though it's inside the class. I've tried searching for solutions to this problem, however the ones I found were not related to my issue.
On top of this, I've tried changing ShipSprite = tex; to the following but with no success:
PlayerShip::ShipSprite = tex; and
this->ShipSprite = tex;
Any ideas for this would be appreciated. Thanks.
Depending on how recent your compiler is, it may not accept initialization of a non-static member that doesn't have integer type. Or it may not know the keyword nullptr.
SDL_Texture * ShipSprite = nullptr;
Try instead
SDL_Texture * ShipSprite;
See if you don't define the include guard (#ifndef PLAYERSHIP_H) somewhere else.
Also, check the output of minGW, which files it uses, maybe your assumptions are wrong? You can also do quick and dirty debug things like introducing a syntax error in your header file. If it isn't caught, the file isn't even used.
Other than that I'd suggest a few other things (unrelated to your question):
Have a naming convention for member variables that is different from that of class names. ShipSprite could be shipSprite_, m_shipSprite, shipSprite, or what have you. (A good set of recommendations: http://geosoft.no/development/cppstyle.html)
If you want to initialize member variables, prefer to do so with the constructor initializer list. I.e.:
PlayerShip::PlayerShip(SDL_Texture * tex) : ShipSprite(tex) {
} The compiler might be more helpful if you are more precise in what you want to do.
It would appear that I may have accidentally compiled the header file separately before I added the variable, and it left a PlayerShip.gch file in the same folder as my headers. GCC probably tried to use it instead of the normal header file and thus gave me that error.
Nonetheless deleting the .gch file seems to have fixed the issue for me and now the program compiles properly. Not sure how I completely missed that.
Thanks again everyone for your suggestions and help.
Edit: How do I go about closing this?
Working with someone else's code here. It compiles just fine with gfortran. Under Portland Group, though, I get an error:
pgf90 -DsysLinux -DcompPGF90 -I/home/cables/GITM/share/Library/src -c -r8 -fast ModUtilities.F90
PGF90-S-0084-Illegal use of symbol mpi_wtime - not public entity of module (ModUtilities.F90: 419)
0 inform, 0 warnings, 1 severes, 0 fatal for sleep
The offending line looks like:
use ModMpi, ONLY : MPI_wtime
(There's obviously a lot of MPI stuff going on here, but I don't think that's the point.) So I go to the source code for ModMpi, which is ModMpi.f90, where I see no reference to MPI_WTIME, but I see:
use ModMpiInterfaces
So finally, I go to the source for ModMpiInterface and I find the line:
public:: mpi_wtime
OK, I was able to get a compile from PGI by editing ModMpi.f90 and declaring mpi_wtime to be public. But still, I wonder: Why did gfortran assume (apparently) that mpi_wtime was public, but PGI had to be told this explicitly? Why does PGI not assume that the original public declaration holds throughout the "use chain"?
I presume that one behavior or the other is closer to the Fortran standard. Which would that be?
For exactly the same Fortran source code (as opposed to some sort of MPI library) compiler behaviour should be the same here.
Whether or not an entity is a public entity of a module is specific to each module that defines or accesses (via USE) that entity. Module A might declare "something" and specify that it is public, module B might USE module A and then specify that same "something" is then private. Any code using module A will be able to access "something", any code only using module B will not.
The default accessibility of things declared in a module is PUBLIC, but that default can be changed by a PRIVATE statement (one without any following identifiers). If such a private statement appeared, you would see the behaviour you describe with the PGI compiler.
Implicit typing (i.e. from source code without IMPLICIT NONE) can also confuse things here.
the context
I'm working on a project having some "modules".
What I call a module here is a simple class, implementing a particular functionality and derivating from an abstract class GenericModule which force an interface.
New modules are supposed to be added in the future.
Several instances of a module can be loaded at the same time, or none, depending on the configuration file.
I though it would be great if a future developer could just "register" his module with the system in a simple line. More or less the same way they register tests in google test.
the context² (technical)
I'm building the project with visual studio 2005.
The code is entirely in a library, except the main() which is in an exec project.
I'd like to keep it that way.
my solution
I found inspiration in what they did with google test.
I created a templated Factory. which looks more or less like this (I've skipped uninteresting parts to keep this question somewhat readable ):
class CModuleFactory : boost::noncopyable
{
public:
virtual ~CModuleFactory() {};
virtual CModuleGenerique* operator()(
const boost::property_tree::ptree& rParametres ) const = 0;
};
template <class T>
class CModuleFactoryImpl : public CModuleFactory
{
public:
CModuleGenerique* operator()(
const boost::property_tree::ptree& rParametres ) const
{
return new T( rParametres );
}
};
and a method supposed to register the module and add it's factory to a list.
class CGenericModule
{
// ...
template <class T>
static int declareModule( const std::string& rstrModuleName )
{
// creation de la factory
CModuleFactoryImpl<T>* pFactory = new CModuleFactoryImpl<T>();
// adds the factory to a map of "id" => factory
CAcquisition::s_mapModuleFactory()[rstrModuleName ] = pFactory;
return 0;
}
};
now in a module all I need to do to declare a module is :
static int initModule =
acquisition::CGenericModule::declareModule<acquisition::modules::CMyMod>(
"mod_name"
);
( in the future it'll be wrapped in a macro allowing to do
DECLARE_MODULE( "mod_name", acquisition::modules::CMyMod );
)
the problem
Allright now the problem.
The thing is, it does work, but not exactly the way i'd want.
The method declareModule is not being called if I put the definition of the initModule in the .cpp of the module (where I'd like to have it) (or even in the .h).
If I put the static init in a used .cpp file .. it works.
By used I mean : having code being called elsewhere.
The thing is visual studio seems to discard the entire obj when building the library. I guess that's because it's not being used anywhere.
I activated verbose linking and in pass n°2 it lists the .objs in the library and the .obj of the module isn't there.
almost resolved?
I found this and tried to add the /OPT:NOREF option but it didn't work.
I didn't try to put a function in the .h of the module and call it from elsewhere, because the whole point is being able to declare it in one line in it's file.
Also I think the problem is similar to this one but the solution is for g++ not visual :'(
edit: I just read the note in the answer to this question. Well if I #include the .h of the module from an other .cpp, and put the init in the module's .h. It works and the initialization is actually done twice ... once in each compilation unit? well it seems it happens in the module's compilation unit ...
side notes
Please if you don't agree with what I'm trying to do, fell free to tell, but I'm still interested in a solution
If you want this kind of self-registering behavior in your "modules", your assumption that the linker is optimizing out initModule because it is not directly referenced may be incorrect (though it could also be correct :-).
When you register these modules, are you modifying another static variable defined at file scope? If so, you at least have an initialization order problem. This could even manifest itself only in release builds (initialization order can vary depending on compiler settings) which might lead you to believe that the linker is optimizing out this initModule variable even though it may not be doing so.
The module registry kind of variable (be it a list of registrants or whatever it is) should be lazy constructed if you want to do things this way. Example:
static vector<string> unsafe_static; // bad
vector<string>& safe_static()
{
static vector<string> f;
return f;
} // ok
Note that the above has problems with concurrency. Some thread synchronization is needed for multiple threads calling safe_static.
I suspect your real problem has to do with initialization order even though it may appear that the initModule definition is being excluded by the linker. Typically linkers don't omit references which have side effects.
If you find out for a fact that it's not an initialization order problem and that the code is being omitted by the linker, then one way to force it is to export initModule (ex: dllexport on MSVC). You should think carefully if this kind of self-registration behavior really outweighs the simple process of adding on to a list of function calls to initialize your "modules". You could also achieve this more naturally if each "module" was defined in a separate shared library/DLL, in which case your macro could just be defining the function to export which can be added automatically by the host application. Of course that carries the burden of having to define a separate project for each "module" you create as opposed to just adding a self-registering cpp file to an existing project.
I've got something similar based on the code from wxWidgets, however I've only ever used it as a DLL. The wxWidgets code works with static libs however.
The bit that might make a difference is that in wx the equivelant of the following is defined at class scope.
static int initModule =
acquisition::CGenericModule::declareModule<acquisition::modules::CMyMod>(
"mod_name"
);
Something like the following where the creation of the Factory because it is static causes it to be loaded to the Factory list.
#define DECLARE_CLASS(name)\
class name: public Interface { \
private: \
static Factory m_reg;\
static std::auto_ptr<Interface > clone();
#define IMPLEMENT_IAUTH(name,method)\
Factory name::m_reg(method,name::clone);\
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.