SWIG immutable std::map reference - c++

I have a typedef in C++ that looks like the following:
typedef std::map<int, TestClass> TestClassMap;
I have another class that returns a const TestClassMap&.
Then in my interface (.i) file for SWIG, I have the following:
namespace std
{
%template(TestClassMap) map<int, myNamespace::TestClass>;
}
This compiles fine and creates the C# library.
However, in the C# library, the function that returns a const TestClassMap& actually returns a TestClassMap that can be changed (is mutable). If I look at the IsReadOnly setting on the returned object, it is false.
From looking at SWIG documentation, it looks like there is a way to mark an object as immutable which I think is what I want. However, I've tried to do this and haven't had any success. I've tried each of the following:
%feature("immutable","1") TestClass;
%immutable TestClass;
%immutable
%template(TestClassMap) map<int, myNamespace::TestClass>;
%mutable
Is there some underlying reason why const std::map<>& cannot be made immutable? Any other ideas?

SWIG does not attempt to preserve const-correctness. Refer to this rant in the documentation:
Although this is clearly a violation of the C++ type-system, fixing the problem doesn't seem to be worth the added implementation complexity that would be required to support it in the SWIG run-time type system. There are no plans to change this in future releases (although we'll never rule anything out entirely).
The bottom line is that this particular issue does not appear to be a problem for most SWIG projects. Of course, you might want to consider using another tool if maintaining constness is the most important part of your project.

Related

List of member reflection in C++ [duplicate]

Is there a way to enumerate the members of a structure (struct | class) in C++ or C? I need to get the member name, type, and value. I've used the following sample code before on a small project where the variables were globally scoped. The problem I have now is that a set of values need to be copied from the GUI to an object, file, and VM environment. I could create another "poor man’s" reflection system or hopefully something better that I haven't thought of yet. Does anyone have any thoughts?
EDIT: I know C++ doesn't have reflection.
union variant_t {
unsigned int ui;
int i;
double d;
char* s;
};
struct pub_values_t {
const char* name;
union variant_t* addr;
char type; // 'I' is int; 'U' is unsigned int; 'D' is double; 'S' is string
};
#define pub_v(n,t) #n,(union variant_t*)&n,t
struct pub_values_t pub_values[] = {
pub_v(somemember, 'D'),
pub_v(somemember2, 'D'),
pub_v(somemember3, 'U'),
...
};
const int no_of_pub_vs = sizeof(pub_values) / sizeof(struct pub_values_t);
To state the obvious, there is no reflection in C or C++. Hence no reliable way of enumerating member variables (by default).
If you have control over your data structure, you could try a std::vector<boost::any> or a std::map<std::string, boost::any> then add all your member variables to the vector/map.
Of course, this means all your variables will likely be on the heap so there will be a performance hit with this approach. With the std::map approach, it means that you would have a kind of "poor man's" reflection.
You can specify your types in an intermediate file and generate C++ code from that, something like COM classes can be generated from idl files. The generated code provides reflection capabilities for those types.
I've done something similar two different ways for different projects:
a custom file parsed by a Ruby script to do the generation
define the types as C# types, use C#'s reflection to get all the information and generate C++ from this (sounds convoluted, but works surprisingly well, and writing the type definitions is quite similar to writing C++ definitions)
Boost has a ready to use Variant library that may fit your needs.
simplest way - switch to Objective-C OR Objective-C++. That languages have good introspection and are full-compatible with C/C++ sources.
also You can use m4/cog/... for simultaneous generation structure and his description from some meta-description.
It feels like you are constructing some sort of debugger. I think this should be doable if you make sure you generate pdb files while building your executable.
Not sure in what context you want to do this enumeration, but in your program you should be able to call functions from Microsofts dbghelp.dll to get type information from variables etc. (I'm assuming you are using windows, which might of course not be the case)
Hope this helps to get you a little bit further.
Cheers!
Since C++ does not have reflection builtin, you can only get the information be teaching separately your program about the struct content.
This can be either by generating your structure from a format that you can use after that to know the strcture information, or by parsing your .h file to extract the structure information.

How can I find all places a given member function or ctor is called in g++ code?

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 }

creating a generic wrapper that returns either std::mem_fn or boost::mem_fn

The KDE/PIM Zanshin project uses std::mem_fn in a number of locations throughout its code, and it turns out that at least 1 version of Apple's clang (the one shipped with the latest Xcode available for OS X 10.9) generates object code that fails to link for a number of the files involved.
It turns out to be possible to circumvent the issue by using boost::mem_fn instead of std::mem_fn. The project's main author is not inclined to increase the boost dependency on all platforms, so I proposed a patch in which a conditional macro is used that expands to boost::mem_fn when required.
The request is now to create a template function that lives in one of zanshin's own namespaces (Utils::mem_fn(f)) and that returns either std::mem_fn(f) or boost::mem_fn(f). And that's the part that's either way above my current paygrade ... or that is simply not feasible independent of the fact that I hardly even understand the purpose of the mem_fn function.
So the question is: is there an easy, compact way to wrap std::mem_fn, ideally with a single template function?
The main hurdle appears to be the return type, but since all uses in zanshin's code appear to return what boils down to a function pointer, I tried using a void* return type. I expected that to fail, and indeed it did.
"The project's main author is not inclined to increase the boost dependency on all platforms"
So instead he burdens the project with inconsistent dependencies? Sounds crooked.
Also, it's not a dependency in the platform-specific sense at all, since you can simply include the relevant headers inside the codebase (see also BCP) and there is no relevant runtime dependency in the first place.
That said, the simpler option would be to have a wrapper that wraps std::mem_fn and at the same exercises (the address of) the referenced member. That way, the linkage problem should actually disappear.
The simplest thing would be (c++14):
template <typename PTMorPTMF>
auto my_mem_fn(PTMorPTMF const& ptm) {
return std::mem_fn(ptm);
}
If you're stuck with c++11:
template <typename PTMorPTMF>
auto my_mem_fn(PTMorPTMF const& ptm) -> decltype(std::mem_fn(ptm)) {
return std::mem_fn(ptm);
}
Simply #ifdef the implementation should you end up implementing it with boost for one platform.

How to create a NSAutoreleasePool without Objective-C?

I have multiplatform game written in C++. In the mac version, even though I do not have any obj-c code, one of the libraries I use seems to be auto-releasing stuff, and I get memory leaks for that, since I did not create a NSAutoreleasePool.
What I want is to be able to create (and destroy) a NSAutoreleasePool without using obj-c code, so I don't need to create a .m file, and change my build scripts just for that. Is that possible? How can that be done?
OBS: Tagged C and C++, because a solution in any of those languages will do.
You can't avoid instantiating the Objective-C runtime—but apparently you've already got one of those.
If you want to interact with the runtime from C, you can us the Objective-C runtime APIs, as documented in Objective-C Runtime Programming Guide and Objective-C Runtime Reference.
The idea is something like this (untested):
#include <objc/runtime.h>
#include <objc/objc-runtime.h>
id allocAndInitAutoreleasePool() {
Class NSAutoreleasePoolClass = objc_getClass("NSAutoreleasePool");
id pool = class_createInstance(NSAutoreleasePoolClass, 0);
return objc_msgSend(pool, "init");
}
void drainAutoreleasePool(id pool) {
(void)objc_msgSend(pool, "drain");
}
If you want to call these functions from another file, of course you'll have to include objc/runtime.h there as well. Or, alternatively, you can cast the id to void* in the return from the allocAndInit function, and take a void* and cast back to id in the drain function. (You could also forward-declare struct objc_object and typedef struct objc_object *id, but I believe that's not actually guaranteed to be the right definition.)
You shouldn't have to pass -lobjc in your link command.
Needless to say, it's probably less work to just make your build scripts handle .m files.

Parsing C++ to make some changes in the code

I would like to write a small tool that takes a C++ program (a single .cpp file), finds the "main" function and adds 2 function calls to it, one in the beginning and one in the end.
How can this be done? Can I use g++'s parsing mechanism (or any other parser)?
If you want to make it solid, use clang's libraries.
As suggested by some commenters, let me put forward my idea as an answer:
So basically, the idea is:
... original .cpp file ...
#include <yourHeader>
namespace {
SpecialClass specialClassInstance;
}
Where SpecialClass is something like:
class SpecialClass {
public:
SpecialClass() {
firstFunction();
}
~SpecialClass() {
secondFunction();
}
}
This way, you don't need to parse the C++ file. Since you are declaring a global, its constructor will run before main starts and its destructor will run after main returns.
The downside is that you don't get to know the relative order of when your global is constructed compared to others. So if you need to guarantee that firstFunction is called
before any other constructor elsewhere in the entire program, you're out of luck.
I've heard the GCC parser is both hard to use and even harder to get at without invoking the whole toolchain. I would try the clang C/C++ parser (libparse), and the tutorials linked in this question.
Adding a function at the beginning of main() and at the end of main() is a bad idea. What if someone calls return in the middle?.
A better idea is to instantiate a class at the beginning of main() and let that class destructor do the call function you want called at the end. This would ensure that that function always get called.
If you have control of your main program, you can hack a script to do this, and that's by far the easiet way. Simply make sure the insertion points are obvious (odd comments, required placement of tokens, you choose) and unique (including outlawing general coding practices if you have to, to ensure the uniqueness you need is real). Then a dumb string hacking tool to read the source, find the unique markers, and insert your desired calls will work fine.
If the souce of the main program comes from others sources, and you don't have control, then to do this well you need a full C++ program transformation engine. You don't want to build this yourself, as just the C++ parser is an enormous effort to get right. Others here have mentioned Clang and GCC as answers.
An alternative is our DMS Software Reengineering Toolkit with its C++ front end. DMS, using its C++ front end, can parse code (for a variety of C++ dialects), builds ASTs, carry out full name/type resolution to determine the meaning/definition/use of all symbols. It provides procedural and source-to-source transformations to enable changes to the AST, and can regenerate compilable source code complete with original comments.