TL;DR
Is there a way to detect using macros/templates/magic if a function was called from a member function or from a free/static function?
Some context
For debugging purposes, I implemented a macro called TRACE(fmt, ...) which writes to file a message with formatted output, with extra information for context (e.g. timestamp, file, function). For an example, calling TRACE("Hello %s", "world!"); will write (2/10/2019 22:32:58 func#file.cpp:27) Hello world!.
Recently, I noticed that in member functions I usually print the address of the object (this) to have some extra context and differentiate between calls to members of different objects.
As this need is very common, I'd want to improve my TRACE macro to output this if invoked from a member function. Unfortunately, I have no idea how to implement this check - "is invoked from a context of a member?"
To clarify, I want to implement a macro TRACE that acts as before in non-member functions, but in member functions the output message will be different and more similar to (2/10/2019 20:32:58 func#file.cpp:27 0x80808080) Hello world!.
To do that, I think I need to differentiate between "macro is invoked from a member function" and "macro is invoked from a non-member function".
My Questions
Can I somehow check if my macro was called from a member function or not?
If not, can I somehow implement the TRACE macro I want to have?
Note that I use GCC, but I'd prefer to have a cross-platform solution.
Things I tried
At first, I tried to check if this is defined, but as it is a keyword it is always "not defined" (defined(this) is false). Moreover, if I try to use this outside of a member function, I get a compilation error. In GCC it is invalid use of 'this' in non-member function. Therefore, it seems that the solution will need to get this information in a more hack-y way, but I'm not sure what it should be.
As an example to how my TRACE macro looks like, you can see this link. I wish that using TRACE in a member function (e.g. in the ctor of A) will "automatically" print the value of this, without needing to pass it explicitly to the macro
Related
I'm calling a function with __func__ as one of the parameters so I can store the name of the function calling that function without having to retype the name of the calling function.
Is there a way of also getting the address of the calling function - a sort of getaddress(__func __) ??
The address will not tell you much; may I instead suggest the predefined macros __FILE__ and __LINE__? They will tell you the current source file (as a char*) and the current line. When you call a function passing those as parameters, you'd know which file/line was the function called from.
They're evaluated by the compiler at the point of usage. If you use them inside the function as opposed to passing them as parameters, they'll tell you the file/line of the function itself.
You can declare function pointers and then assign specific functions to them. So then you could have an array or other collection of such pointers as your table.
If this works for you and you accept the answer, I'm willing to come back and create a short summary here. (I know I'm not supposed to answer with just-a-link.) But see if this approach will do what you want.
https://www.learncpp.com/cpp-tutorial/78-function-pointers/
There is no portable standard C++ way to do this. You could use compiler/OS specific hacks, the same was as in C, but it's less useful in C++ since it only works on extern "C" names (where the __FUNCTION__/__func__ match what dlsym expects).
Since that hack only works on extern "C" names, this means you can't use it for templated functions, class methods, or function overloading (same function name, different argument prototypes), which is fairly restrictive. Mind you, even typing out the function name wouldn't work in some of those cases already (e.g. the name alone doesn't describe the prototype, so function overloading wouldn't work).
I think you need to rethink a design that's essentially demanding reflection in C++; the nature of optimizing compilers is that most of the functions you define don't actually have to exist, or if they do, they exist only with names that are meaningless to anything but the compiler. When you ask to dynamically determine the address of the current function from within the function, you're assuming the function exists, with an actual address, in the final compiled binary, when it could just as easily have been inlined into each actual call site, partially merged with a near identical function, etc.
I came across a question regarding writing a code to determine unused functions in C++. We can use different data structures to determine unused functions. But before that, we need to parse the code. I have question related to parsing part, how we can differentiate functions declaration and definition and function-calls?
Like,
//function declaration without argument
fun1 ();
//function definition
fun1 () {
// code goes here
}
main () {
fun1 ();
}
Above declaration and call is looks same where as definition part is little bit different from declaration and call.
Other than above scenario, there are multiple scenario for calling a function and functions scope, like two classes having function with same name one function get called within member function (i.e. no explicit calling object required) OR function call using object so, need to understand object's type first to determine which function is actually called.
How can parsing implemented efficiently? How many parsing will required in above scenario?
This is how you can distinguish them:
//function definition
return_type fun1 (args) {
// code goes here
}
Note that function definition has a "return type" before the function name.
Also, note that a function declaration looks exactly the same as its definition. You don't actually need to distinguish them until you see either ; or {. That is the point in which you make the decision whether its a declaration or definition. In your particular application, you don't really care about it because you don't care what the function actually does.
Unfortunately for you, C++ is complicated. To determine which functions are useless, you actually need at least a basic semantic analysis. This includes at least the type system.
What is worse, is that some function may not necessarily be called directly, but through a virtual function. So your static analysis of the code shows only the parent's function getting called, while in reality it's the child's.
Will adding an argument to member function gonna change the behavior of the function?
Need help about this concept.
The behavior won't change if you only add an argument to the prototype of the function.
However you will have to change all the call to this function since the prototype changed, this isn't the same function anymore.
And sincerely, I don't see the point of adding an argument if you don't modify the code afterward.
You'll need to give us more information. Like an example. But say you add a new argument (and provide a default), and now argument will be "constructed" and destructed everywhere the member function was called. So it's possible that that in itself has side-effects (e.g. print to console on creationg and destruction).
Is there a way to determine how many parameters a Lua function takes just before calling it from C/C++ code?
I looked at lua_Debug and lua_getinfo but they don't appear to provide what I need.
It may seem a bit like I am going against the spirit of Lua but I really want to bullet proof the interface that I have between Lua and C++. When a C++ function is called from Lua code the interface verifies that Lua has supplied the correct number of arguments and the type of each argument is correct. If a problem is found with the arguments a lua_error is issued.
I'd like to have similar error checking the other way around. When C++ calls a Lua function it should at least check that the Lua function doesn't declare more parameters than are necessary.
What you're asking for isn't possible in Lua.
You can define a Lua function with a set of arguments like this:
function f(a, b, c)
body
end
However, Lua imposes no restrictions on the number of arguments you pass to this function.
This is valid:
f(1,2,3,4,5)
The extra parameters are ignored.
This is also valid:
f(1)
The remaining arguments are assigned 'nil'.
Finally, you can defined a function that takes a variable number of arguments:
function f(a, ...)
At which point you can pass any number of arguments to the function.
See section 2.5.9 of the Lua reference manual.
The best you can do here is to add checks to your Lua functions to verify you receive the arguments you expect.
You can determine the number of parameters, upvalues and whether the function accepts variable number of arguments in Lua 5.2, by using the 'u' type to fill nups, nparams, isvararg fields by get_info(). This feature is not available in Lua 5.1.
I wouldn't do this on the Lua side unless you're in full control of Lua code you're validating. It is rather common for Lua functions to ignore extra arguments simply by omitting them.
One example is when we do not want to implement some methods, and use a stub function:
function do_nothing() end
full_api = {}
function full_api:callback(a1, a2) print(a1, a2) end
lazy_impl = {}
lazy_impl.callback = do_nothing
This allows to save typing (and a bit of performance) by reusing available functions.
If you still want to do function argument validation, you have to statically analyze the code. One tool to do this is Metalua.
No, not within standard Lua. And is Aaron Saarela is saying, it is somewhat outside the spirit of Lua as I understand it. The Lua way would be to make sure that the function itself treats nil as a sensible default (or converts it to a sensible default with something like name = name or "Bruce" before its first use) or if there is no sensible default the function should either throw an error or return a failure (if not name then error"Name required" end is a common idiom for the former, and if not name then return nil, "name required" end is a common idiom for the latter). By making the Lua side responsible for its own argument checks, you get that benefit regardless of whether the function is called from Lua or C.
That said, it is possible that your modules could maintain an attribute table indexed by function that contains the info you need to know. It would require maintenance, of course. It is also possible that MetaLua could be used to add some syntax sugar to create the table directly from function declarations at compile time. Before calling the Lua function, you would use it directly to look up any available attributes and use them to validate the call.
If you are concerned about bullet-proofing, you might want to control the function environment to use some care with what (if any) globals are available to the Lua side, and use lua_pcall() rather than lua_call() so that you catch any thrown errors.
The information you ask for is not available in all cases. For example, a Lua function might actually be implemented in C as a lua_CFunction. From Lua code there is no way to distinguish a pure Lua function from a lua_CFunction. And in the case of a lua_CFunction, the number of parameters is not exposed at all, since it's entirely dependent on the way the function is implemented.
On the other hand, what you can do is provide a system for functions writers (be it in pure Lua or in C) to advertise how many parameters their functions expect. After creating the function (function f(a, b, c) end) they would simply pass it to a global function (register(f, 3)). You would then be able to retrieve that information from your C++ code, and if the function didn't advertise its parameters then fallback to what you have now. With such a system you could even advertise the type expected by the parameters.
Here's something I know is probably possible but I've never managed to do
In VS2005(C++), While debugging, to be able to invoke a function from the code which I'm debugging.
This feature is sometimes essential when debugging complex data structures which can't be explored easily using just the normal capabilities of the watch window.
The watch window seem to allow writing function calls but every time I try it it gives me one error or another.
Error: symbol "func" not found
Error: argument list does not match function
Error: member function not present
Did anyone ever succeed in making this work properly?
What am I missing here?
Edit: clearly, the function called should be a symbol that exists in the current scope the debugger is in.
Ok, Here's what I found
CXX0040 means that "The C expression evaluator does not support implicit conversions involving constructor calls."
CXX0047 means that "Overloaded functions can be called only if there is an exact parameter match or a match that does not require the construction of an object."
So combined it means that If I want to call a function none of the arguments should have an implicit conversion and none of the arguments should need a construction.
"implicit conversion" in this context seem to include trivial things like converting 'String' to 'const String&'.
"construction" seem to include trivial copy-construction. so passing by value anything that is not a primitive type will result in an error.
So this basically leaves functions that take only primitive types or pointers.
I have just tested this theory successfully.
So if you want to be able to call a method from the watch window, add an overload which takes only pointers and primitives and in the watch window pass the arguments appropriately. To pass an object that is not a primitive pass its address.
The watch window is limited by the context wherein your current code is, e.g., when your code enters a function and you try to access another function that is hidden from the scope of your current function, it won't work.
If you invoke a function in the watch window, make sure that it is visible and accessible from the current scope.
To my knowledge, you can't execute code from the Watch window while debugging unmanaged C++. This does work for C# (and probably VB.NET and managed C++, but I'm not positive on that). So likely it allows it because it works for some languages, but not others.
We find this works in a very hit and miss manner. Some very simple functions (incl. member functions) work, typically simple property getters. Other more complex functions don't work and give an error.
I've never been able to discern the precise rules ...
I haven't tested this, but I always thought that was what the immediate window was for (executing code)
Cameron
It's the "Immediate" window that you want. And you're limited to what's visible from where your current breakpoint is. Local variables, and functions on that class (or globals)
In my experience, there are some shortcomings with the immediate window. You can't call your classes' member functions if the classes come from a different DLL, but get misleading error messages. If anything is in the same DLL (e.g. by statically linking in all other stuff), calling members is fairly reliable. But complex stuff may or may not work, as mentioned by others.