I have a class containing:
class SomeClass {
SomeClass *previous;
static __declspec(thread) SomeClass *stackTop;
public:
SomeClass() : previous(stackTop) { stackTop = this; }
~SomeClass() { stackTop = previous; }
};
__declspec(thread) SomeClass *SomeClass::stackTop = NULL;
This compiles fine for Win32 target, but when compiling for Pocket PC 2003 (ARMV4) fails with error C2485:
error C2485: '$I' : unrecognized extended attribute
in the two places where I set the member in SomeClass constructor and destructor and in all places where I instantiate SomeClass (it is instantiated as automatic variable and needs to know where the next instance higher up the stack is).
Unfortunately the error has no meaningful documentation in MSDN and the documentation for __declspec(thread) does not indicate any conditions under which it will not work. I did check that thread is not defined in preprocessor.
I don't believe that version of Pocket PC (Windows CE) supports the __declspec(thread) attribute (TLS). It would explain why this only comes up when you're compiling for Pocket PC but not for Win32. See the following links:
Windows CE does not
support the __declspec(thread)
attribute
__declspec (thread) returns
error
Related
I've been porting some c++ app from Visual Studio 2013 to Visual Studio 2017. Aside from the plethora of new warnings that I had to fix, the compilation and linking went okay.
However, when running the app, it 'stalled' when trying to re-enter the constructor of a singleton (when successive function calls form a loop back to the constructor). It seems that this behaviour was okay in VS2013, but is no longer valid in VS2017. There is no error message.
I'm aware of all the bad things related to singletons, and that there should at least not be loops. The question is not there.
Is there a way to tell the VS2017 compiler that I'd like to shoot myself in the foot, and allow the same behaviour that was there in VS2013?
I don't have access to the code that causes this behaviour because it comes from a third-party library, this is why I can't 'just fix it', unfortunately.
Here is an example which works in VS2013, but doesn't work in VS2017:
main.cpp
#include "Singleton.h";
int
main( void )
{
std::cout << "let's do this!" << std::endl;
int two = Singleton::GetReference().getTwo();
std::cout << "ok" << std::endl;
return 0;
}
Singleton.h
#pragma once
class Stuff;
class Singleton
{
public:
static Singleton& GetReference();
int getTwo() { return 2; }
private:
Singleton();
Stuff* stuff;
};
Singleton.cpp
#include "Singleton.h"
#include "Stuff.h"
Singleton&
Singleton::GetReference() {
static Singleton theInstance;
return theInstance;
}
Singleton::Singleton()
{
stuff = new Stuff();
}
Stuff.h
#pragma once
class Stuff
{
public:
Stuff();
private:
int two;
};
Stuff.cpp
#include "Stuff.h"
#include "Singleton.h"
Stuff::Stuff()
{
two = Singleton::GetReference().getTwo();
}
In the code above, when step-by-step debugging, the first time we get on the line static Singleton theInstance; will work as expected, but the second time, a F11 will go to the file thread_safe_statics.cpp, into the method extern "C" void __cdecl _Init_thread_header(int* const pOnce). A Shift+F11 will exit the method and the program will wait indefinitely at the line specified (observed when pausing the program from the debugger).
PS
This issue probably occurs in Visual Studio 2015 too, as the documentation linked from the accepted answer mentions VS2015.
/Zc:threadSafeInit-
The general "Conformance" page is MSDN: Conformance, which details which new features you can disable.
I needed the code for sizedDealloc, where my new compiler was creating a sized new operator for a library which broke older compiled expectations.
As this is a compile flag, at least some of the code would be in your control, and you should be able to unravel the beast.
The constructor Stuff::Stuff is calling a function on an incompletely constructed object.
That would create "Undefined behavior". If the value "2" is not set till the end of the constructor (for example).
Probably the Singleton needs to be split into 2, one which delivers the early static data (e.g. 2).
The second which delivers the held object Stuff. Stuff would only rely on the first, which would break the deadlock.
Alternatively, a second constructor to Stuff which told it which object to use, and was called from the Singleton::Singleton
The MSDN article to disable "Magic Statics" MSDN : disable threadsafe static initialization
I'm currently writing an application using MFC and CLR in visual studio, and my program is crashing whenever I call the constructor of a class I've written (the class is to control a camera over USB).
I've got a base class CameraBase:
class CameraBase
{
public:
virtual bool getFrame(cv::Mat& outImage) { return true; };
};
and a derived class LumeneraCamera (for the specific camera):
class LumeneraCamera : public CameraBase
{
public:
DLL_API LumeneraCamera();
DLL_API bool connect(int cameraNum);
DLL_API bool disconnect();
DLL_API bool getFrame(cv::Mat& outImage);
private:
//Bunch of misc variables
};
These classes are compiled into a DLL and accessed from another program:
int main()
{
cout << "Initing camera" << endl;
camera = new LumeneraCamera();
//More operations
}
When I run the program, it prints Initing camera and then fails because of an assertion in dllinit.cpp (line 133: VERIFY(AfxInitExtensionModule(controlDLL, hInstance));). It crashes before executing anything in the constructor. I'm not really sure what the problem is but it seems tied to MFC, so I'm currently looking into untangling my project from MFC entirely. Any suggestions or fixes are appreciated!
According to MSDN, if your DLL is dynamically linked against the MFC DLLs, each function exported from this DLL which call into MFC must have the AFX_MANAGE_STATE macro added at the very beginning of the function:
AFX_MANAGE_STATE(AfxGetStaticModuleState());
I eventually solved it by disabling MFC - a library I was using suggested MFC but as far as I can tell works fine without it.
I am using Qt 4.8.5 with MSVC 2010 compiler and debugger from windows 7.0 SDK, and Qt creator as my IDE.
The following syntax works fine:
class Device
{
public:
Device();
....
QVector<double> MyContainer;
....
protected:
....
}
, where QContainer can be QVector, QList...etc, and T can be any type.
But the following syntax is denied by Qt creator and shows "Error C2059" while attempting to compile:
class Device
{
public:
Device();
....
QVector<double> MyContainer(100);
....
protected:
....
}
I am so confused since the document says the syntax "QContainer = MyContainer(szie)"is legitimate, but my Qt creator just can't read and it tells me there is an "unexpected token '('".
Am I doing worng?
It's because you are trying to assign to a type. QVector<double> is a type, and not a variable declaration or anything else you can assign to. That means that both examples are actually wrong.
I think you mean to declare the member variable MyContainer, for which you should use
QVector<double> MyContainer;
To initialize the container to a specific size, you have to use the constructors initializer list:
Device()
: MyContainer(100)
{
...
}
For more information about initializer lists, see e.g. this tutorial, or this reference.
I am working on porting a game from visual studio to xcode the game was completely written in c++ and I am having some troubles with dynamic casting that I never had when running in visual studio. I am wondering if it is a compiler issue or some things are just not supported in the mac environment, any help will be greatly appreciated. Here is a stripped down version of the code that I am running in xcode which will crash when doing the dynamic_cast
class base {
public:
int dm;
virtual void vm(){}
base(){}
};
class specific : public base {
public:
virtual void vm(){dm++;}
specific (){}
};
specific* sp = new specific();
base* b = (base*) sp;
specific * s = dynamic_cast< specific * >( b );
You can try to set "Enable Runtime Type" = YES
Build setting > Apple LLVM 5.0 - Language - C++
In your xcode project.
hope this help.
I'm running into a strange crash. I am trying to separate out various modules of my Application (MFC based, developed in VS2005) into DLLs. Following is the skeletal code of how I'm trying to achieve it:
In a common Header file(say base.h):
class Base {
vector<message> messages;
...
...
};
In a header file in DLL source code(say class.h):
class Derived : public Base {
private:
int hoo();
...
public:
void foo();
int goo();
...
};
extern "C" __declspec (dllexport) Derived* CreateDerived();
In class.cpp
Derived* CreateDerived()
{
return new Derived;
}
In a file in main Application code:
#include "base.h"
#include "class.h"
typedef Derived* (*DerivedCreator)();
...
...
void LoadDll()
{
//DLL Load Code...
...
...
DerivedCreator creator = reinterpret_cast<DerivedCreator>(::GetProcAddress(dllHandle, "CreateDerived"));
Derived* pDerived = creator();
pDerived->messages.push_back(message("xyz"));//Crashes here...
}
The problem is the code craches the moment I try to access the vector member of the Base class. This only happens in Release mode. It works fine in Debug mode. The error message that i get when I execute it from Visual Studio in Release mode is:
"Microsoft Visual Studio C Runtime Library has detected a fatal error in Samsung SSD Magician.exe.
Press Break to debug the program or Continue to terminate the program."
But when I execute the release binary directly and attach the debugger to it, I get an Access Violation. At this point if I check the vector in debugger, it shows 6-digit entries in it, none of them readable. I'm able to see correct values of rest of the members of Base class in the Derived pointer.
Any help would be much appreciated.
It's dangerous to pass stl containers across a DLL boundary.
The reason here is that each module (the main application and the DLL) has it's own instance of the heap. If you allocate dynamic memory in the context of DLL, then pass the pointer to the application and release that memory in the context of the application, that causes heap corruption.
That is exactly what happens in your example.
Derived* pDerived = creator();
CreateDerived is called.
Derived* CreateDerived()
{
return new Derived;
}
new Derived allocates memory in DLL heap.
pDerived->messages.push_back(message("xyz"));
Inside push_back, an additional memory is allocated for Base::messages, and that allocation is done on the application heap. Crash!
A conclusion is that you need to rethink the DLL interface in order to perform all operation on the vector only inside the DLL.