lately I have been faced with a strange problem that a simple source did not want to compile. I was looking for solutions (and cause) in many sites but without good effects (except bugs reports but I have not found there direct cause ).
Below I present simple code to reproduce that situation:
struct Foo {
Foo() : m_x( true ) {}
__property bool x = { read=m_x };
private:
bool m_x;
};
template<typename T>
struct TMyPointer {
T * m_ptr;
TMyPointer( T * ptr ) : m_ptr( ptr ) {}
~TMyPointer()
{
delete m_ptr;
}
T * operator->() const
{
return Get();
}
T * Get() const
{
if( m_ptr == NULL )
; // some error handling
return m_ptr;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
TMyPointer<Foo> bar( new Foo );
if( bar->x && 1 == 1 ) ; // Failed
if( 1 == 1 && bar->x ) ; // OK
if( !!bar->x && 1 == 1 ) ; // OK
if( bar->x == true && 1 == 1 ) ; // OK
if( (bar->x) && 1 == 1 ) ; // OK
return 0;
}
Compiler has failed to compile first condition inside main function. What stranger compilation of other equivalent conditions is finished successfully.
That's behavior I have only during release compilation. To reproduce I have used Embarcadero® C++Builder® XE5 Version 19.0.13476.4176
Error message: [bcc32 Fatal Error] File1.cpp(43): F1004 Internal
compiler error at 0x14470090 with base 0x14410000
Anybody knows what is the problematic in above example? Maybe usage templates with properties mechanism is the cause?
In my case is simple solution it seems to be problematic condition inside Get method. When I change
if( m_ptr == NULL )
to equivalent form
if( !m_ptr )
everything compile without errors.
I am writing about it here becouse I would like to share my insights - it can be helpfully for somebody.
recently I got similar ICE (once my source code grows in size) and your solution seemingly helped for a while but not really as after some minor changes in code ICE resurfaced again. Based on the behavior of mine problem:
IDE: BDS2006 Turbo C++ explorer (its version of BCB between BCB6 and RAD)
Huge win32 project (several MBytes of code involving USB,OpenGL,CAD/CAM)
Each part of code is tested for years and compilable separably problem occurs once they together and code grows too big
Project compiles fine at first run but after that any recompile fails
The temporary workaround was to close IDE, delete all obj,tds,exe,... files restart IDE and compile again.
I assumed compiler and or IDE leaks or overwrites some parts of itself corrupting its functionality. As the problem persist after IDE restart without deleting temp files I assumed it has something to do with debug info stored in them.
So I played with Project->Options->Debugging settings and turning off this:
Inline function expansion (-vi)
Helped (not even IDE restart or temp file removal was needed).
Don't have enough reputation to upvote or comment someone else's posts, but I have recently found the same solution as in #Spektre reply.
Disabling Inline function expansion fixed our multiple-year problems with completely unrelated internal compiler errors on random projects. We only experienced them on MSBUILD scripts in Release config.
I found this out by going over all the compiler options in Release config that were different from Debug config and changed them one-by-one to match Debug config through msbuild parameters for the entire solution/projectgroup. And eventually it started to build without any errors when I've disabled Inline function expansion option.
These problems happened and I confirmed the fix on C++ Builder XE5;
This kept on resurfacing at random for as long as I can remember (Borland C++ 2006 and later)
The older developers used to try and revert latest commits until it started compiling again... Which is a pain in the behind.
Anyone looking for solution to pass a parameter to an MSBUILD command (for all targets in the script) add this line to the msbuild.exe call:
msbuild.exe Targets.xml /p:BCC_InlineFunctionExpansion=false /t:Build
Related
If you test the following code, it compiles and runs without issue:
#include <iostream>
using namespace std;
class Parent
{
public:
Parent(bool flag) : flag(flag) {}
virtual void display() = 0;
protected:
bool flag;
};
class Child : public Parent
{
public:
Child(bool flag) : Parent(flag) {}
Child(const Child & rhs) : Parent(rhs.flag) {}
virtual void display() { cout << flag << endl; }
};
int main()
{
// Set Flag to true
Child tru(true);
Child * storage [2];
storage[0] = new Child(tru);
storage[0]->display();
// Set Flag to false
Child * container = new Child(storage[0]);
delete storage[0];
storage[0] = new Child(false);
storage[0]->display();
// Set Flag to true
storage[1] = new Child(container);
storage[1]->display();
return 0;
}
However, after I plug this snippet into my program, the Child objects consistently change their bool flag to true between the time they are created with the copy constructor and the time I actually attempt to display their bool flag value. I know the change initially sticks thanks to copious amounts of cout lines calling values at every step of the way, but when my display function is called, their values all switch to true.
I haven't been able to successfully reproduce the error, externally, but while I attempt to do so, I'm hoping someone might have an idea of what could possibly interfere with this process? Is there a common error, mistake or conflict I should be checking for in a situation like this?
storage[1] = new Child(container); will create the new object passing the pointer container to the new object.
I seriously doubt this is what you intended. Did you mean to type storage[1] = new Child(*container); (passing the reference to the pointed-to object?)
Remember a pointer is (essentially) a numerical-address, thus can evaluate to true (!= 0) or false ( == 0), thus:
storage[1] = new Child(container); evaluates as storage[1] = new Child(container != 0); (and that is new Child(0xffcd3ds != 0); //example memory address, thus calling the standard constructor taking bool, rather than the copy-constructor.
Take into account that that error also specifies the same issue one line 32 Child * container = new Child(storage[0]);, the exact same bug can be found here (thus container's object will be false anyway), however it's slightly more subtle given child * [] can be used as child **. But I imagine you can figure it out with ease.
Note that this kind of comparison may seem like a "trap" if your learning programming, however I assure you, such quick-and-dirty "is the pointer null" comparisons are a huge help in more complex projects.
In furtherance, I ran your snippet though the Visual-Studio compiler - it output the following compile log (successfully building the project)
1>------ Build started: Project: Project1, Configuration: Debug Win32 ------
1> playground.cpp
1>c:\users\USER\documents\visual studio 2015\projects\project1\playground.cpp(32): warning C4800: 'Child *': forcing value to bool 'true' or 'false' (performance warning)
1>c:\users\USER\documents\visual studio 2015\projects\project1\playground.cpp(38): warning C4800: 'Child *': forcing value to bool 'true' or 'false' (performance warning)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
(the following is not meant to have any emotion, I realize on reading it does sound somewhat sarcastic, it is meant in sincerity).
Note that those two warnings (effectively) tell you what I just did above, assuming whatever compiler you are using outputs a similar error (I'd be surprised if it didn't), the lesson here will be what I tell my apprentice every-day, always read the compiler-output log - obviously if your compiler doesn't output such a warning, remember the lesson anyway.
Slightly useful tip
If you are able to do so, please consider using the C++11 Smart Pointers, I note that you never call delete before you return 0, doing so is a soft error, and may leak memory on some systems.
Everything compiles fine, but during run time, it crashes without any coredumps, exceptions or no logs clues about what is happening. After inserting debug lines, I found that it was around this section of code
if( MISC_TABLE_ID != tableID )
{
OrbSchemaStructure orbSchemaStruct;
orbSchemaStruct.tableName = tableView;
orbSchemaStruct.columnName = colName;
orbSchemaStruct.dataType = tsFact->convertDBDataTypeToEVDataType( toString( col.type() ) );
orbSchemaStruct.primaryKeyComponent = pkComponent;
schemaStructureDeque.push_back( orbSchemaStruct ); //crashes after this line
}
And it is happening on the last line of this block, where the push_back happens.
and the schemaStructureDeque happens to be an object of type DEQUE< OrbSchemaStructure >& schemaStructureDeque where DEQUE is a define for std::deque.
The OrbSchemaStructure is a struct defined in an idl as follows :
struct OrbSchemaStructure
{
string tableName;
string columnName;
unsigned long dataType;
boolean primaryKeyComponent;
};
Was there any change to the way deques are handled? Am I missing something?
Before writing this question off as too localized, please let me know if I am missing any info, or if I am not looking in the right place.
I am using omniORB 4.0.4 btw.
On compiling in the omniORB on AIX using the new AIX 11.1 C++ compiler, and linking it with the binary, it has stopped crashing.
I have a code with possible floating point overflows which cannot be managed by checking arguments of functions. I have to define _matherr and throw an exception from inside it in order to give a chance to caller to manage the problem.
There is something strange: in Debug build, _matherr is called as supposed, but not in Release. I use CodeGear C++ Builder 2007. Under MSVC 2010 the handler works fine, but I need VCL features for the whole application. Googling gives nothing but messages about _matherr not working in DLL (that is known from documentation).
And my question is: what could be the reason for _matherr to not work in Release?
// One of the methods with overflows.
double DoubleExponential::F(double x) const
{
try
{
double y=pow(fabs(x),a);
return 0.5 + sign(x)*G(y,1/a)/(2*G(1/a));
}
catch(PowExpOverflow)
{
return 0.5;
}
}
// Exception.
struct PowExpOverflow {};
int _matherr (struct _exception *a){
Application->MessageBox("Inside custom _matherr", "", MB_OK);
if (a->type == OVERFLOW)
if (!strcmp(a->name,"pow") ||
!strcmp(a->name,"powl") ||
!strcmp(a->name,"exp") ||
!strcmp(a->name,"expl"))
{
throw PowExpOverflow();
}
return 0;
}
The problem is due to bug in the dynamic RTL which I use in the release build (description). The bug was not fixed in the version of IDE I use, so the only working solution is to upgrade to a higher version. Nevertheless, having a clear explanation helps a lot.
I'm using VS 2010 to program in C++.
In debug mode I usually am able to see the content every object/container that I am using, even the ones that comes from the STL. Except that for the following "Entity_set_z_ordered" set, I am unable to see the content of my container, in debug mode it just shows a "?"
struct z_orderer {
bool operator() ( const Entity* lhs, const Entity* rhs) const{
return (lhs->getPosition().y < rhs->getPosition().y || ( (lhs->getPosition().y == rhs->getPosition().y) && lhs->getPosition().x < rhs->getPosition().x));
}
};
std::set<Entity*, z_orderer> Entity_set_z_ordered;
Any idea of where this is coming from or how I could debug this? I haven't changed any of the default Debug setting
thanks
edit : I solved it, the problem was that struct z_orderer was defined inside my main function and not outside of it. I'm not sure if this would have created problems during runtime, but at least I can debug it now!
For anyone else that stumbles across this... this happened to me when I had
a getter property in a class model pointing to itself. It was a copy paste error, notice the property name below is ShouldNotProcess, and in the getter it's returning itself. The return was supposed to be: return !this.ShouldProcess;
public bool ShouldNotProcess
{
get { return !this.ShouldNotProcess; }
}
I have a unit test project based on UnitTest++. I usually put a breakpoint to the last line of the code so that the I can inspect the console when one of the tests fails:
n = UnitTest::RunAllTests();
if ( n != 0 )
{
// place breakpoint here
return n;
}
return n;
But I have to reinsert it each time I check-out the code anew from SVN. Is it possible to
somewhat place the breakpoint by the compiler?:
n = UnitTest::RunAllTests();
if ( n != 0 )
{
// place breakpoint here
#ifdef __MSVC__
#!!!$$$??___BREAKPOINT;
#endif
return n;
}
return n;
Use the __debugbreak() intrinsic(requires the inclusion of <intrin.h>).
Using __debugbreak() is preferable to directly writing __asm { int 3 } since inline assembly is not permitted when compiling code for the x64 architecture.
And for the record, on Linux and Mac, with GCC, I'm using __builtin_trap().
DebugBreak(void)
From Winbase.h.
MSDN
You could use this in C or C++
__asm
{
int 3
}
If you are using VC6 (yes, outdated but still in use in some places/projects), DebugBreak() will work but you may end up in some obscure location deep withing Windows DLLs, from which you have to walk the stack up back into your code.
That's why I'm using ASSERT() in MFC or assert() in "standard" code.
Your example would work like this:
n = UnitTest::RunAllTests();
ASSERT(n == 0);
//assert(n == 0);
return n;
If you don't need a result and want it just for debugging, you can also do
if(0 != UnitTest::RunAllTests())
{
ASSERT(FALSE);
//assert(false);
}
How about using a Debug or Trace method to output the console info. That may be a better approach than relying on breakpoints.
How often do you check out the project from SVN? This is typically something I only do once per project, or when I rebuild my PC.
If you also checkin the project files, the breakpoints should be stored in the project files.
I think it is in the .suo file. You could also put that under SVN control if you wanted, though I prefer not to.