code within statically linked library src files returning null - visual-c++

This is for windows using MSVC compiler version 14.28.29910:
Libraries built using colcon. This was meant for a ROS2 application but I dont believe ROS has anything to do with it.
I have been stuck on this issue for two days now and I still am at a loss as to what is going on. Any help will be greatly appreciated.
I have a library that I am statically linking against. Library A. it is built with colcon. Could this be a linking issue or an issue with the fact that I build library A with a certain set of preprocessors and I build library B with a different set of preprocessors that change the Gameobject class to a different version shown below but same function implementations.
ament_auto_add_library(A STATIC
${SOURCES}
${HEADERS}
)
ament_target_dependencies(A ${ALL_DEPENDS})
install(TARGETS
A
EXPORT A_export
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
ament_export_libraries(A_export HAS_LIBRARY_TARGET)
I then link to it from a ros2 package using the standard
target_link_libraries(B A)
I have a object called Gameobject that is defined in library A.
#file --------------------------Gameobject.h
#ifdef InLibraryA
class Gameobject
{
int GetPosx(){return data.x;}
}
#else
class Gameobject
{
int GetPosx(){return data.x;}
}
#endif
#file --------------------------MoveGameObject.h
class MoveGameObject
{
int MoveGObj_inline(Gameobject* g)
{
return g->getPosx();
}
int MoveGObj(Gameobject* g);
}
#file --------------------------MoveGameObject.cpp
int MoveGameObject::MoveGObj(Gameobject* g)
{
return g->getPosx();
}
Now in library B , I do this within a subscription callback
SomeCallback()
{
Gameobject* g = GetGObjectFromPool();
MoveGameObject* m= new MoveGameObject();
//this will return NULL value
int posx = m->MoveGObj(g);
//this will be fine because it was inlined?
int possx = m->MoveGObj_inline(g);
}
You will see that I get null when calling the function that was NOT inlined for calling the getter function from Gameobject. I dont get null for the inlined function even though they run the exact same code. Note that this only happens to non-inline functions that call Gameobject functions. Does not happen to functions that do not read memory from Gameobject. addingTwoInts() for example works fine Non-inline. There are no errors. It is undefined behavior. Any ideas on what I could be doing wrong for this to happen? The simplified code above is the same as to what is happening in my code, just removed unnecessary details.

Related

Visual C++ lambdas always output debug information

If I instantiate a lambda somewhere (and the compiler doesn't inline it), I can find a string showing where the lambda is located in my c++ code like this:
... ?AV<lambda_1>#?0??MyFunction#MyScopedClass#MyNamespace##SAXXZ# ...
I don't want this information in the executable, as it could give away important names of classes and functions.
All kinds of output debug information are turned off. If I use a normal function instead, the final executable doesn't have this information, so manually converting all lambdas into normal functions would "fix it". But what's the best way to handle this? Can we tell the compiler to transform lambdas into normal functions?
UPDATE: I tested with other compilers: g++ and clang. They both leave the same references. I also found another unanswered question about this Gcc - why are lambdas not stripped during release build Please don't come with the "why do you care about a few symbols anyway".
Here's some code you can test with:
#include <iostream>
#include <functional>
class MyUnscopedClass
{
public:
MyUnscopedClass(const std::function<void(int x)>& f) :
f(f)
{
}
std::function<void(int x)> f;
};
namespace MyNamespace
{
class MyScopedClass
{
public:
static void temp1(int x)
{
std::cout << x * (x + 1);
}
static void MyFunction()
{
//MyUnscopedClass obj(temp1); // no symbols
MyUnscopedClass obj([](int x) // ?AV<lambda_1>#?0??MyFunction#MyScopedClass#MyNamespace##SAXXZ#
{
std::cout << x;
});
obj.f(23);
}
};
}
int main()
{
MyNamespace::MyScopedClass::MyFunction();
}
With the help of #dxiv in the comments, I found the problematic setting.
Configuration Properties > General > C++ Language Standard
can't be, for some reason,
Preview - Features from the Latest C++ Working Draft (std:c++latest)
So I set it to the second most recent one
ISO C++17 Standard (std:c++17)
and I get a random identifier instead.
AV<lambda_f65614ace4683bbc78b79ad57f781b7f>##
I'm still curious how this identifier is chosen though.

Lambda expressions (C++0x) not working in C++/CLI? [duplicate]

One of the cool new C++ features in Visual Studio 2010 are lambda expressions. However, I can't get them to work within a managed class.
class UnmanagedClass {
void Foo() {
// Creating empty lambda within unmanaged class.
// This compiles fine.
auto lambda = [](){ ; };
}
};
ref class ManagedClass {
void Foo() {
// Creating empty lambda within managed class.
// This creates error C3809:
// A managed type cannot have any friend functions/classes/interfaces.
auto lambda = [](){ ; };
}
};
My best guess is that the compiler creates the anonymous function class as a friend class, even though I never use class members. This seems to mean that lambdas cannot be used at all within ref classes.
I was so happy when I read that VS2010 adds lambda expressions to C++. Does anybody know how to get them to work within ref classes?
Looks like it is being considered for future versions. Otherwise known as: "We'll get to it."

Why the bad_alloc(const char*) was made private in Visual C++ 2012?

I am just trying to compile a bit bigger project using the Visual Studio 2012 Release Candidate, C++. The project was/is compiled using the VS2010 now. (I am just greedy to get the C++11 things, so I tried. :)
Apart of things that I can explain by myself, the project uses the code like this:
ostringstream ostr;
ostr << "The " __FUNCTION__ "() failed to malloc(" << i << ").";
throw bad_alloc(ostr.str().c_str());
The compiler now complains
error C2248: 'std::bad_alloc::bad_alloc' : cannot access private member declared
in class 'std::bad_alloc'
... which is true. That version of constructor is now private.
What was the reason to make that version of constructor private? Is it recommended by C++11 standard not to use that constructor with the argument?
(I can imagine that if allocation failed, it may cause more problems to try to construct anything new. However, it is only my guess.)
Thanks,
Petr
The C++11 Standard defines bad_alloc as such (18.6.2.1):
class bad_alloc : public exception {
public:
bad_alloc() noexcept;
bad_alloc(const bad_alloc&) noexcept;
bad_alloc& operator=(const bad_alloc&) noexcept;
virtual const char* what() const noexcept;
};
With no constructor that takes a string. A vendor providing such a constructor would make the code using it not portable, as other vendors are not obliged to provide it.
The C++03 standard defines a similar set of constructors, so VS didn't follow this part of the standard even before C++11. MS does try to make VS as standard compliant as possible, so they've probably just used the occasion (new VS, new standard) to fix an incompatibility.
Edit: Now that I've seen VS2012's code, it is also clear why the mentioned constructor is left private, instead of being completely removed: there seems to be only one use of that constructor, in the bad_array_new_length class. So bad_array_new_length is declared a friend in bad_alloc, and can therefore use that private constructor. This dependency could have been avoided if bad_array_new_length just stored the message in the pointer used by what(), but it's not a lot of code anyway.
If you are accustomed to passing a message when you throw a std::bad_alloc, a suitable technique is to define an internal class that derives from std::bad_alloc, and override ‘what’ to supply the appropriate message.
You can make the class public and call the assignment constructor directly, or make a helper function, such as throw_bad_alloc, which takes the parameters (and additional scalar information) and stores them in the internal class.
The message is not formatted until ‘what’ is called. In this way, stack unwinding may have freed some memory so the message can be formatted with the actual reason (memory exhaustion, bad request size, heap corruption, etc.) at the catch site. If formatting fails, simply assign and return a static message.
Trimmed example:
(Tip: The copy constructor can just assign _Message to nullptr, rather than copy the message since the message is formatted on demand. The move constructor, of course can just confiscate it :-).
class internal_bad_alloc: public std::bad_alloc
{
public:
// Default, copy and move constructors....
// Assignment constructor...
explicit internal_bad_alloc(int errno, size_t size, etc...) noexcept:
std::bad_alloc()
{
// Assign data members...
}
virtual ~internal_bad_alloc(void) noexcept
{
// Free _Message data member (if allocated).
}
// Override to format and return the reason:
virtual const char* what(void) const noexcept
{
if (_Message == nullptr)
{
// Format and assign _Message. Assign the default if the
// format fails...
}
return _Message;
}
private:
// Additional scalar data (error code, size, etc.) pass into the
// constructor and used when the message is formatted by 'what'...
mutable char* _Message;
static char _Default[];
}
};
//
// Throw helper(s)...
//
extern void throw_bad_alloc(int errno, size_t size, etc...)
{
throw internal_bad_alloc(errno, size, etc...);
}

VTable Not Generated

First of all, thank you very much for taking the time to look at my question. Second, I have read this and my class does not have any virtual methods I am forgetting to include. I'll go over additional things I have tried after I describe my problem.
I am getting an undefined reference to `vtable for SubcomponentTypeWidget' error when I build my code using gcc version 3.4.6 20060404. Visual Studio 2005 has no issues. I love Linux, but my current political situation has delegated it to the red headed step child that regularly suffers abuse. Hopefully by our powers combined, I can remedy that.
I am using Qt version 4.6.2. I am using gcc 3.4.6 20060404 on Red Hat 4.
This is my header:
#ifndef SubcomponentTypeWidget_h
#define SubcomponentTypeWidget_h
#include <vector>
#include "ui_SubcomponentTypeWidget.h"
#include "Subcomponent.h"
class SubcomponentTypeWidget : public QWidget, public Ui::SubcomponentTypeWidget
{
Q_OBJECT
Q_PROPERTY(QString title READ title WRITE setTitle)
public:
SubcomponentTypeWidget(QWidget* parent,
Models::Subcomponent::SubcomponentType subcomponentType = Models::Subcomponent::kSolid)
: QWidget(parent),
m_subcomponentType(subcomponentType),
m_subcomponentTypeButtonGroup(new QButtonGroup(this))
{
this->initialize();
}
Models::Subcomponent::SubcomponentType subcomponentType() const { return m_subcomponentType; }
void setSubcomponentType(Models::Subcomponent::SubcomponentType type);
void setNonCompatibleTypes(const std::vector<Models::Subcomponent::SubcomponentType>& types);
QString title() const { return m_subcomponentGroupBox->title(); }
void setTitle(const QString &title) { m_subcomponentGroupBox->setTitle(title); }
signals:
void subcomponentTypeChanged();
protected slots:
void handleSubcomponentTypeChoice(int subcomponentTypeChoiceId);
protected:
void initialize();
Models::Subcomponent::SubcomponentType m_subcomponentType;
QButtonGroup* m_subcomponentTypeButtonGroup;
};
#endif // SubcomponentTypeWidget_h
The implementation is here:
#include "SubcomponentTypeWidget.h"
void SubcomponentTypeWidget::setSubcomponentType(Models::Subcomponent::SubcomponentType type)
{
if (type != m_subcomponentType)
{
m_subcomponentType = type;
emit subcomponentTypeChanged();
}
}
void SubcomponentTypeWidget::setNonCompatibleTypes(const std::vector<Models::Subcomponent::SubcomponentType>& types)
{
m_subcomponentTypeButtonGroup->button(static_cast<int>(Models::Subcomponent::kSolid) + 1)->setEnabled(true);
m_subcomponentTypeButtonGroup->button(static_cast<int>(Models::Subcomponent::kComplement) + 1)->setEnabled(true);
m_subcomponentTypeButtonGroup->button(static_cast<int>(Models::Subcomponent::kHole) + 1)->setEnabled(true);
for (std::vector<Models::Subcomponent::SubcomponentType>::const_iterator it = types.begin(); it != types.end(); ++it)
{
m_subcomponentTypeButtonGroup->button(static_cast<int>(*it) + 1)->setEnabled(false);
if (*it == m_subcomponentType)
m_subcomponentTypeButtonGroup->button(static_cast<int>(Models::Subcomponent::kSolid) + 1)->setChecked(true);
}
}
void SubcomponentTypeWidget::handleSubcomponentTypeChoice(int subcomponentTypeChoiceId)
{
if (static_cast<Models::Subcomponent::SubcomponentType>(subcomponentTypeChoiceId - 1) != m_subcomponentType)
{
m_subcomponentType = static_cast<Models::Subcomponent::SubcomponentType>(subcomponentTypeChoiceId - 1);
emit subcomponentTypeChanged();
}
}
void SubcomponentTypeWidget::initialize()
{
this->setupUi(this);
m_subcomponentTypeButtonGroup->addButton(m_solidRadioButton, static_cast<int>(Models::Subcomponent::kSolid) + 1);
m_subcomponentTypeButtonGroup->addButton(m_complementRadioButton, static_cast<int>(Models::Subcomponent::kComplement) + 1);
m_subcomponentTypeButtonGroup->addButton(m_holeRadioButton, static_cast<int>(Models::Subcomponent::kHole) + 1);
m_subcomponentTypeButtonGroup->button(static_cast<int>(m_subcomponentType) + 1)->setChecked(true);
connect(m_subcomponentTypeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(handleSubcomponentTypeChoice(int)));
}
The actual error messages I am receiving are:
../lib/libMeshAndGeometry.a(AddAdvancedDialog.o)(.gnu.linkonce.t._ZN20Ui_AddAdvancedDialog7setupUiEP7QDialog+0x955): In function `Ui_AddAdvancedDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddAdvancedDialog.o)(.gnu.linkonce.t._ZN20Ui_AddAdvancedDialog7setupUiEP7QDialog+0x960): In function `Ui_AddAdvancedDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddAdvancedDialog.o)(.gnu.linkonce.t._ZN20Ui_AddAdvancedDialog7setupUiEP7QDialog+0x99b): In function `Ui_AddAdvancedDialog::setupUi(QDialog*)':
: undefined reference to `SubcomponentTypeWidget::initialize()'
../lib/libMeshAndGeometry.a(AddBoxDialog.o)(.gnu.linkonce.t._ZN15Ui_AddBoxDialog7setupUiEP7QDialog+0xfe8): In function `Ui_AddBoxDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddBoxDialog.o)(.gnu.linkonce.t._ZN15Ui_AddBoxDialog7setupUiEP7QDialog+0xff3): In function `Ui_AddBoxDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddBoxDialog.o)(.gnu.linkonce.t._ZN15Ui_AddBoxDialog7setupUiEP7QDialog+0x102e): In function `Ui_AddBoxDialog::setupUi(QDialog*)':
: undefined reference to `SubcomponentTypeWidget::initialize()'
../lib/libMeshAndGeometry.a(AddConeDialog.o)(.gnu.linkonce.t._ZN16Ui_AddConeDialog7setupUiEP7QDialog+0x7ef): In function `Ui_AddConeDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddConeDialog.o)(.gnu.linkonce.t._ZN16Ui_AddConeDialog7setupUiEP7QDialog+0x7fa): In function `Ui_AddConeDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddConeDialog.o)(.gnu.linkonce.t._ZN16Ui_AddConeDialog7setupUiEP7QDialog+0x835): In function `Ui_AddConeDialog::setupUi(QDialog*)':
: undefined reference to `SubcomponentTypeWidget::initialize()'
../lib/libMeshAndGeometry.a(AddCylinderDialog.o)(.gnu.linkonce.t._ZN20Ui_AddCylinderDialog7setupUiEP7QDialog+0x9c4): In function `Ui_AddCylinderDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddCylinderDialog.o)(.gnu.linkonce.t._ZN20Ui_AddCylinderDialog7setupUiEP7QDialog+0x9cf): In function `Ui_AddCylinderDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddCylinderDialog.o)(.gnu.linkonce.t._ZN20Ui_AddCylinderDialog7setupUiEP7QDialog+0xa0a): In function `Ui_AddCylinderDialog::setupUi(QDialog*)':
All of my makefiles have been generated from my .pro file using qmake. The main make files, the main .pro file, and the widgets and MeshAndGeometry make and .pro files are attached here as an archive. One of the .ui files is attached here.
I have tried a number of things.
I am sure this is not a stale object file issue. I have built this from scratch and I still have the the problem.
I checked all of my capitalization issues. One of the problems I have noticed with doing most of this on Windows and then moving it to Linux is that people make mistakes with capitalization, and Windows doesn't care about capitalization.
I ran nm -a -C SubcomponentTypeWidget.o to see if the necessary vtable was there, and it wasn't. However, the 'missing' methods were there.
Creating a virtual destructor does not force vtable generation for SubcomponentTypeWidget.
I have tried removing large chunks of SubcomponentTypeWidget's functionality. This results in removing the specific linker error messages for methods, but it does not remove the undefined reference to vtable message. I have removed everything from SubcomponentTypeWidget other than the constructor, and in this case I still receive the "undefined reference to vtable" message, but without any mention to specific methods we are looking for.
Changing the order of which widgets and MeshingAndGeometry are linked in does not help.
I have tried gcc versions 3.4.6 20060404 and 4.1.2 20080704.
Help me, Obi-Wan Kenobi. You're my only hope.
Thank you all very, very much,
-Brian J. Stinar-
went through your codes the error most likely arises from the following statement:
=======================================================
void SubcomponentTypeWidget::initialize()
{
this->setupUi(this);
//rest of codes
}
=======================================================
you are sort of breaking the structure of Qt by making SubcomponentTypeWidget a subclass of Ui::SubcomponentTypeWidget. You are actually using yourself to setup a UI of yourself in this case. Coupled that with the fact that you are using multiple class inheritance, you are just confusing the compiler on which virtual method to refer to during runtime.
Instead of subclassing Ui::SubcomponentTypeWidget, just make it a private variable in SubcomponentTypeWidget
//SubcomponentTypeWidget.h
private:
Ui::SubcomponentTypeWidge ui;
implement the following in your init function and you should be good to go
void SubcomponentTypeWidget::initialize()
{
ui.setupUi(this);
//rest of codes
}
My problem was with solution point number six. I actually did NOT change this order correctly. I was changing the order in the INCPATH instead of the order in the LIBS.
After adding the line MeshAndGeometry.depends = widgets to my master.pro file, running qmake, and running make, this problem went away.
Thank everyone very much for their comments and help.
-Brian J. Stinar-

inserting "this" into an STL map from the constructor

VERSION 1
class Doh {
private:
static std::map<const std::string, const Doh*> someMap;
std::string stringValue_;
public:
Doh(std::string str) : stringValue_(str) {
Doh::someMap.insert(
std::make_pair<const std::string,const Doh*>
(this->stringValue_,this)
);
}
}
The above was ok with MSVC 2010 but with MSVC 2008 it fails – and I guess it is because the object is not constructed yet when it is inserted in the map (I got a memory access violation).
So, I tried a delayed insertion, which worked:
VERSION 2
Doh(std::string str) : stringValue_(str) {
boost::thread(&Doh::insertIntoTheStaticMap,this);
}
void insertIntoTheStaticMap() {
boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
Doh::someMap.insert(
std::make_pair<const std::string,const Doh*>
(this->stringValue_,this)
);
}
But as you might be able to guess, my intention is to have the static Doh::someMap as a common lookup dictionary.
VERSION 1 didn’t need any thread-safety because I would create all Doh instances in the same thread – in initialization blocks - which would be called by dynamic initializers before I enter main().
But with VERSION 2, the naïve sleep() is neither graceful nor reliable (not to mention, I might need to lock the map before insertion).
What would be a nice KISS approach?
Only potential issue I see is the initialization of the static member, if there are multiple source files. Try guarding it with a function.
class Doh {
private:
static std::map< std::string, Doh * > &get_map() {
static std::map< std::string, Doh * > someMap;
return someMap; // initialize upon first use
}
std::string stringValue_;
public:
Doh(std::string str) : stringValue_(str) {
get_map().insert(
std::make_pair
(this->stringValue_,this)
);
}
};
In neither version is there any sign of init for stringvalue_ - what does the debugger show you about this key when you hit the map insert in version 1 of the code? How is this field set up, and what is its type?
Running this in the debugger for VS2008 should allow you to narrow down the point of failure into the <map> source, I would have thought.

Resources