My codebase is C++ on NXP ARM M4 with custom C++ RTOS.
There exists a certain function, DWB() aka DangerWillRobinson(), that if called could have unexpected side-effects (which are valid when it's used correctly).
DWB() could be called in a very deeply nested manner as in
A()->B()->C()->D()->...->DWB()
I want author of any functions that, directly or indirectly, call DWB() to be aware that DWB() is called and I want to force them to acknowledge that they know DWB() is called.
I know this could be accomplished by parsing the linker's generated call-trees using Python but I'd much prefer this to be a compile-time error thing.
Here's how I'd like this to work:
void A()
{
B();
}
Author goes to compile:
ERROR: DWB() is called. Please acknowledge.
Author then thinks about side-effects of calling DWB() and finds no issues.
void A()
{
// some macro-thing ... ?
B();
}
If possible, I do not want this to be a runtime check. I think in theory, this is possible. If Base is inherited, I would like all possible classes' call-trees to be considered; it's ok if none of them are even instantiated but not ideal.
QUESTION
Is this compile-time metadata/behavior of a function possible?
Is this compile-time metadata/behavior of a function possible?
No, it isn't. There might be some configurable SCA tools available (consider a commercial high level one), but not with plain c-preprocessing or meta-template-programming magic.
I want author of any functions that, directly or indirectly, call DWB() to be aware that DWB() is called and I want to force them to acknowledge that they know DWB() is called.
The least intrusive way to do that is to mark the DWB() function [[deprecated]].
I just suppose you prefer to factor out such error prone function in a midterm roadmap, and replace it with something more stable.
The most quick way in case you are sure what all the conditions of a correct DWB() call are is to apply a bunch of assert() calls at the start of that function.
There might come up complaints from fellow developers, which are trying to use that function incorrectly. Give them best advice as you can in the assertion messages.
Related
I'm looking to make a general, lazy evaluation-esque procedure to streamline my code.
Right now, I have the ability to speed up the execution of mathematical functions - provided that I pre-process it by calling another method first. More concretely, given a function of the type:
const Eigen::MatrixXd<double, -1, -1> function_name(const Eigen::MatrixXd<double, -1, -1>& input)
I can pass this into another function, g, which will produce a new version of function_name g_p, which can be executed faster.
I would like to abstract all this busy-work away from the end-user. Ideally, I'd like to make a class such that when any function f matching function_name's method signature is called on any input (say, x), the following happens instead:
The class checks if f has been called before.
If it hasn't, it calls g(f), followed by g_p(x).
If it has, it just calls g_p(x)
This is tricky for two reasons. The first, is I don't know how to get a reference to the current method, or if that's even possible, and pass it to g. There might be a way around this, but passing one function to the other would be simplest/cleanest for me.
The second bigger issue is how to force the calls to g. I have read about the execute around pattern, which almost works for this purpose - except that, unless I'm understanding it wrong, it would be impossible to reference f in the surrounding function calls.
Is there any way to cleanly implement my dream class? I ideally want to eventually generalize beyond the type of function_name (perhaps with templates), but can take this one step at a time. I am also open to other solution to get the same functionality.
I don't think a "perfect" solution is possible in C++, for the following reasons.
If the calling site says:
result = object->f(x);
as compiled this will call into the unoptimized version. At this point you're pretty much hamstrung, since there's no way in C++ to change where a function call goes, that's determined at compile-time for static linkage, and at runtime via vtable lookup for virtual (dynamic) linkage. Whatever the case, it's not something you can directly alter. Other languages do allow this, e.g. Lua, and rather ironically C++'s great-grandfather BCPL also permits it. However C++ doesn't.
TL;DR to get a workable solution to this, you need to modify either the called function, or every calling site that uses one of these.
Long answer: you'll need to do one of two things. You can either offload the problem to the called class and make all functions look something like this:
const <return_type> myclass:f(x)
{
static auto unoptimized = [](x) -> <return_type>
{
// Do the optimizable heavy lifting here;
return whatever;
};
static auto optimized = g(unoptimized);
return optimized(x);
}
However I very strongly suspect this is exactly what you don't want to do, because assuming the end-user you're talking about is the author of the class, this fails your requirement to offload this from the end-user.
However, you can also solve it by using a template, but that requires modification to every place you call one of these. In essence you encapsulate the above logic in a template function, replacing unoptimized with the bare class member, and leaving most everything else alone. Then you just call the template function at the calling site, and it should work.
This does have the advantage of a relatively small change at the calling site:
result = object->f(x);
becomes either:
result = optimize(object->f, x);
or:
result = optimize(object->f)(x);
depending on how you set the optimize template up. It also has the advantage of no changes at all to the class.
So I guess it comes down to where you wan't to make the changes.
Yet another choice. Would it be an option to take the class as authored by the end user, and pass the cpp and h files through a custom pre-processor? That could go through the class and automatically make the changes outlined above, which then yields the advantage of no change needed at the calling site.
I'd like some advice on how to check for the correctness of the parameters I receive.
The checking is going to be done in C++, so if there's a good solution using Boost.Python (preferably) or the C API, please tell me about that. Otherwise, tell me what attributes the object should have to ensure that it meets the criteria.
So...
How do you check that an object is a function?
How do you check that an object is a bound method?
How do you check that an object is a class object?
How do you check that a class object is a child of another class?
When in doubt just work out how you would get the required effect by calling the usual Python builtins and translate it to C/C++. I'll just answer for Python, for C you would look up the global such as 'callable' and then call it like any other Python function.
Why would you care about it being a function rather than any other sort of callable? If you want you can find out if it is callable by using the builtin callable(f) but of course that won't tell you which arguments you need to pass when calling it. The best thing here is usually just to call it and see what happens.
isinstance(f, types.MethodType) but that won't help if it's a method of a builtin. Since there's no difference in how you call a function or a bound method you probably just want to check if it is callable as above.
isinstance(someclass, type) Note that this will include builtin types.
issubclass(someclass, baseclass)
I have two unconventional recommendations for you:
1) Don't check. The Python culture is to simply use objects as you need to, and if it doesn't work, then an exception will occur. Checking ahead of time adds overhead, and potentially limits how people can use your code because you're checking more strictly than you need to.
2) Don't check in C++. When combining Python and C (or C++), I recommend only doing things in C++ that need to be done there. Everything else should be done in Python. So check your parameters in a Python wrapper function, and then call an unchecked C++ entry point.
I have a function (actually from ATL, it is ATL::CSoapMSXMLInetClient::SendRequest(LPCTSTR)) whose behaviour should slightly be modified. That is, I just have to add one function call somewhere in the middle of the function.
Taking into consideration that this is not a template method, what is the best practice of changing its behaviour? Do I have to re-write the whole function?
Thanks in advance.
EDIT: Deriving from the class ATL::CSoapMSXMLInetClient and copy-pasting whole function code with a slight modification in subclass function definition does not work because most of the members used in ATL::CSoapMSXMLInetClient::SendRequest are "private" and accessing them in subclass is a compile time error.
Rather than best practice I am looking for a way to do it now, if there is any. :(
Yes you will. If it's in the middle of the function there is no way of getting around it.
There are some refactoring methods you can use. But I cannot think of any pretty ones, and all depend heavily on the code within the class, although for you case it might be tough to find any that works.
Like if you have a line:
do_frobnicate();
dingbat->pling();
And you need to call somefunc() after the dingbat plings. You can, if the dingbat is an interface that you provide, make a new dingbat that also do somefunc() when it plings. Given that the only place this dingbat plings is in this function.
Also, if do_frobnicate() is a free function and you want to add the somefunc() after this, you could create a function within the class, or within its namespace that is called the same. That way you make your own do_frobnicate() that also does somefunc().
Simple answer would be Protocol.
The another point is that it is said that all methods in ObjectC are virtual, so no need to say virtual in ObjC.
I find it hard to understand this concept.
Any comments to figure out more clear around this question ?
Thanks for commenting.
Simple answer would be Protocol.
Simple but wrong. A protocol is an interface specification. It's a collection of messages that an object must (ignoring the #optional keyword for now) respond to.
The term "virtual function" has no direct counterpart in Objective-C. In Objective-C you don't call functions on objects, you send messages to them. The object itself then decides how to respond to the message, typically by looking up the message in its class object, finding the associated method and invoking it. Note that this all happens at run time, not compile time.
The mapping between messages (or "selectors" to give them their technical term) and methods is built entirely from the #implementation. The method declarations in the #interface are only there to give the compiler the information it needs to warn you that you may have forgotten a method implementation. And it is only a warning because you can't tell until run time whether whether the object really does respond to the message or not. For example, somebody else could add a category to an existing class that provides implementations for missing methods, or a class could override forwardingTargetForSelector: to forward messages it doesn't respond to elsewhere.
Methods on objects in Objective-C are not virtual functions, they are real functions.
I beg to differ, methods in Obj-C aren't quite real like one would expect. They behave just like virtual functions in C++ do, except you cannot make a 'pure virtual' function in Objective-C.
Cheers,
Raxit
in C++, I can easily create a function pointer by taking the address of a member function. However, is it possible to change the address of that local function?
I.e. say I have funcA() and funcB() in the same class, defined differently. I'm looking to change the address of funcA() to that of funcB(), such that at run time calling funcA() actually results in a call to funcB(). I know this is ugly, but I need to do this, thanks!
EDIT----------
Background on what I'm trying to do:
I'm hoping to implement unit tests for an existing code base, some of the methods in the base class which all of my modules are inheriting from are non-virtual. I'm not allowed to edit any production code. I can fiddle with the build process and substitute in a base class with the relevant methods set to virtual but I thought I'd rather use a hack like this (which I thought was possible).
Also, I'm interested in the topic out of technical curiosity, as through the process of trying to hack around this problem I'm learning quite a bit about how things such as code generation & function look-up work under the hood, which I haven't had a chance to learn in school having just finished 2nd year of university. I'm not sure as to I'll ever be taught such things in school as I'm in a computer engineering program rather than CS.
Back on topic
The the method funcA() and funcB() do indeed have the same signature, so the problem is that I can only get the address of a function using the & operator? Would I be correct in saying that I can't change the address of the function, or swap out the contents at that address without corrupting portions of memory? Would DLL injection be a good approach for a situation like this if the functions are exported to a dll?
No. Functions are compiled into the executable, and their address is fixed throughout the life-time of the program.
The closest thing is virtual functions. Give us an example of what you're trying to accomplish, I promise there's a better way.
It cannot be done the way you describe it. The only way to change the target for a statically bound call is by modifying the actual executable code of your program. C++ language has no features that could accomplish that.
If you want function calls to be resolved at run-time you have to either use explicitly indirect calls (call through function pointers), or use language features that are based on run-time call resolution (like virtual functions), or you can use plain branching with good-old if or switch. Which is more appropriate in your case depends on your specific problem.
Technically it might be possible for virtual functions by modifying the vtable of the type, but you most certainly cannot do it without violating the standard (causing Undefined Behavior) and it would require knowledge of how your specific compiler handles vtables.
For other functions it is not possible because the addresses of the functions are directly written to program code, which is generally on a read-only memory area.
I am fairly sure this is impossible in pure C++. C++ is not a dynamic language.
What you want is a pointer to a function, you can point it to FuncA or FuncB assuming that they have the same signature.
You cannot do what you want to do directly. However, you can achieve a similar result with some slightly different criteria, using something you are already familiar with -- function pointers. Consider:
// This type could be whatever you need, including a member function pointer type.
typedef void (*FunctionPointer)();
struct T {
FunctionPointer Function;
};
Now you can set the Function member on any given T instance, and call it. This is about as close as you can reasonably get, and I presume that since you are already aware of function pointers you're already aware of this solution.
Why don't you edit your question with a more complete description of the problem you're trying to solve? As it stands it really sounds like you're trying to do something horrible.
Its simple!
For
at run time calling funcA() actually results in a call to funcB().
write funcA() similar to following:
int funcA( int a, int b) {
return funcB( a, b );
}
:-)