How to print input c++ function parameter values automatically - c++

I was wondering if there is a macro or standard way (for debugging purposes) to automatically print the value of the parameters of a function f, just like __FUNCTION__ prints/shows the function signature? For example,
void foo(int x, string y) {
cout << __FUNCTIION_ARGS__ << endl;
}
should show the values of x, and y.
If there is no such magic the standard way, is it possible to write a macro/template to do this?
--Update--
Per #jxh's comment, if print inside the function in question is impossible with macro/templates, is it possible to do it automatically on the caller-side, with something like:
call(foo,x,y);
which prints every parameter value, and behaves the same with foo(x,y) as if it is called directly in every other aspect? If a value is not printable (e.g. pointers, functions), the wrapper call can just print an opaque value such as <ptr> or <noprint>.
Thanks
P.S. I am using gcc, (and also clang in the future).

My take on it :
#include <iostream>
// Dummy parameter-pack expander
template <class T>
void expand(std::initializer_list<T>) {}
// Fun
template <class Fun, class... Args>
typename std::result_of<Fun&&(Args&&...)>::type
call(Fun&& f, Args&&... args) {
// Print all parameters
std::cout << "Params : ";
expand({(std::cout << args << ' ', 0)...});
std::cout << '\n';
// Forward the call
return std::forward<Fun>(f)(std::forward<Args>(args)...);
}
// Random test function
int myFunc(std::string const &s, double d, int i) {
std::cout << s << ' ' << d << ' ' << i << '\n';
return 57;
}
int main()
{
// Painless call
std::cout << call(myFunc, "hello", 3.14, 42) << '\n';
return 0;
}
Output :
Params : hello 3.14 42
hello 3.14 42
57
Variadic templates are fun !

There is no macro for printing the arguments, but you can print the function prototype using the __PRETTY_FUNCTION__ macro

Related

High level print function for C++ [duplicate]

This question already has answers here:
How do I print out the arguments of a function using a variadic template?
(3 answers)
Closed 2 years ago.
Is there a way to create a function or a macro in C++ that you can use like Python?
What i mean is a function like:
print(i); // i is an integer.
print(i, s); // i is an integer, s is a std::string. They are separated by a white space.
A function that takes in a number of arguments, then just prints them out regardless of the types.
Use streams:
std::cout << i << ' ' << s << '\n';
For more complex formatting consider fmt, it supports the syntax for python's str.format as well as printf style formatting (but typesafe).
If you are allowed to use C++17, you can do it using fold-expression, like this:
#include <iostream>
template<class ...Args>
void print(const Args &...args) {
auto seq_started = false;
auto print_impl = [&](auto &value) mutable {
if (seq_started) {
std::cout << " " << value;
} else {
seq_started = true;
std::cout << value;
}
};
(print_impl(args), ...);
}
int main() {
print("foo", 10, "bar", 20, "baz");
return 0;
}
I assume that the question is about general solution and that print is just an example.
The answer is: yes, with a combination of overloads and templates. First you setup functions per type:
void print_impl(const std::string& arg) {
std::cout << arg;
}
void print_impl(int arg) {
// Note: this is an example. Of course cout already
// does that for us with simple
// std::cout << arg;
print_impl(convert_to_string(arg));
}
// cout already has lots of overloads, we can take
// advantage of that if needed:
template<class TArg>
void print_impl(TArg&& arg) {
std::cout << std::forward<TArg>(arg);
}
then templates:
template<class TArg>
void print(TArg&& arg) {
print_impl(std::forward<TArg>(arg));
}
template<class TArg1, class ... TArgs>
void print(TArg1&& arg1, TArgs&& ... args) {
print_impl(std::forward<TArg1>(arg1)); // <-- print first argument
print_impl(" "); // <-- insert separator, requires const std::string& overload
print(std::forward<TArgs>(args)...); // <-- recursive call
}
In the code above you can replace calls to print_impl with calls to std::cout << operator directly, if needed. Although I would keep print_impl because it is a nice layer above std::cout in case you want to replace it in the future.
Then you can use it similar to Python:
int main()
{
print("test");
print(1, 2, "foo");
print("foo", 1, 2);
return 0;
}

Is it possible to get the name of a function passed to a template?

I try to get the name of a class method on runtime which is passed to a templated class method. I would like to know the name for better trace output.
The question results from the question that I asked before:
Templated wrapper method for other class methods
I tried to get the name by adding
typeid(func).name()
But the result is not really satisfying because the name of the function is always printed as a *, see the examples below.
I also tried different compilers (msvc, gcc) and demangle options (abi::__cxa_demangle), but the result is always more or less the same.
#include <algorithm>
#include <functional>
#include <iostream>
class A
{
public:
void foo(int x) {
std::cout << "Foo: " << x << std::endl;
}
void bar(int x, float y) {
std::cout << "Bar: " << x << ", " << y << std::endl;
}
};
class B
{
public:
void fooAndMore(int x) {
foobarWrapper(&A::foo, x);
}
void barAndMore(int x, float y) {
foobarWrapper(&A::bar, x, y);
}
template<typename T, typename... Args>
void foobarWrapper(T func, Args&&... args)
{
std::cout << "Start!" << std::endl;
auto funcName = typeid(func).name();
std::cout << "Functionname: " << funcName << std::endl;
auto caller = std::mem_fn( func);
caller( A(), args...);
std::cout << "End!" << std::endl;
}
};
int main()
{
B b;
b.fooAndMore(1);
b.barAndMore(2, 3.5f);
}
I expected something like that:
Start!
Functionname: void (__thiscall A::foo)(int)
Foo: 1
End!
Start!
Functionname: void (__thiscall A::bar)(int,float)
Bar: 2, 3.5
End!
Actual results:
Start!
Functionname: void (__thiscall A::*)(int)
Foo: 1
End!
Start!
Functionname: void (__thiscall A::*)(int,float)
Bar: 2, 3.5
End!
Is it possible to get the real name of the passed function?
Thank you in advance!
No. typeid only does RTTI for polymorphic objects (i.e. objects of class type, with virtual functions). For all other types, it'll just give you information about the static type, in this case a function pointer type. (typeid for polymorphic objects leverages the vtable to do its work, but there's no vtable-like thing attached to functions.)
For debugging/tracing of this sort, you'll need to use platform-specific debugging utilities.

How do we change this function to support multiple arguments?

#include <iostream>
using namespace std;
class SampleClass
{
public:
int test(int ... arguments)
{
cout << arguments[0] << endl; // Access first element in array
return sizeof(arguments);
}
};
int main()
{
SampleClass lol;
cout << lol.test(3, 1, 4, 2, 5, 0) << endl;
return 0;
}
The test function fails due to my limited understanding in C++ semantics. But how can I fix it so that it can access the FIRST element in the arguments lits and then return the size of arguments?
As #Nik pointed out, I could obviously pass in an array, but there is no real fun with that! I am trying to do this just for learning - to see if this is even possible in C++.
Since we're all guessing at what you want, I'll throw in:
template <typename ... Ts>
size_t test(Ts ... arguments) {
auto unused = { 0, ((cout << '[' << arguments << "]\n"), 0)...};
(void)unused;
return sizeof...(arguments);
}
which works with different types of arguments (Live at Coliru). This solution is a bit too "clever" to be readable, though.
The trick here is to build a braced-initializer-list - the {...} stuff - whose elements are initialized by processing the variadic arguments in order. You then convince the compiler that said initializer list isn't used for anything, so the code will be optimized to just generate the desired side effects.
The comma operator in C++ evaluates to the value of the rightmost subexpression. The other subexpressions are evaluated and their values discarded. So ((cout << '[' << arguments << "]\n"), 0) has the effect of dumping some stuff to cout - including one of the variadic parameters - and evaluates to 0. After expanding the pack with the ... that line of code is effectively:
auto unused = { 0, ((cout << '[' << arg0 << "]\n"), 0),
((cout << '[' << arg1 << "]\n"), 0),
((cout << '[' << arg2 << "]\n"), 0) };
The cout junk is evaluated for its side effects and discarded, the whole thing is deduced as a std::initializer_list<int> just as if we had written
auto unused = { 0, 0, 0, 0 };
(The extra zero is there at the beginning to avoid a syntax error if someone calls the function with no arguments at all.)
The (void)unused; line is casting unused to void. It will compile to absolutely nothing, but also will typically tell compilers not to warn us about unused being an unused variable.
try something like this
double test( int num, ... )
{
va_list arguments; // A place to store the list of arguments
double sum = 0;
va_start ( arguments, num ); // Initializing arguments to store all values after num
for ( int x = 0; x < num; x++ ) // Loop until all numbers are added
sum += va_arg ( arguments, double ); // Adds the next value in argument list to sum.
va_end ( arguments ); // Cleans up the list
return sum / num; // Returns the average
}
so youre points are on the wrong side of your parameter list.
i hope this helps and goodluck.
Hm. You are trying to mix two features of C++, variadic-templates and variable-length argument list.
Your code will not compile at all, since you have no templates here and for variable-length argument list declaration should be
int test(int arguments...)
and you can access values from this list with functions from cstdarg header.
With variadic-templates you can do following thing
class Derived
{
public:
template<int... arguments>
int test()
{
int array[] = {arguments...};
return sizeof(array) / sizeof(*array);
}
};
use it like
cout << lol.test<3, 1, 4, 2, 5, 0>() << endl;
I am not quite sure I fully understand your question. If you want access to "the first" argument to the function rather than the template, I think something like this will do it for you, but I may be completely misunderstanding your purpose here:
#include <iostream>
template<typename... Args>
int foo(int arg0, Args... args);
template<>
int foo(int arg0)
{
// here just to catch expansion
std::cout << '[' << arg0 << ']' << std::endl;
return 1;
}
template<typename... Args>
int foo(int arg0, Args... args)
{
foo(arg0);
foo(args...);
return 1 + sizeof...(args);
}
int main()
{
std::cout << foo(1,2,3,4,5) << std::endl;
std::cout << foo(100,200,300) << std::endl;
int a=10, b=20;
std::cout << foo(a,b) << std::endl;
return 0;
}
Output
[1]
[2]
[3]
[4]
[5]
5
[100]
[200]
[300]
3
[10]
[20]
2
You have several options.
1) use an ellipse (only way to have unlimited arg list):
int foo(int a1, ...);
Your code will need to parse the ellipse like printf does. you'll be limited to builtin C types.
2) Use multiple templates:
template<typename T1> int foo(T1 a1);
template<typename T1, typename T2> int foo(T1 a1, T2 a2);
// more templates for more arguments
This method us used, usually up to 10 parameters (10 template functions)
3) Use a function with defaults or illegal values so you'll know which is the last valid argument:
int foo(int a1, int a2 = -1, int a3 = -1, int aN = -1);

Designing a better API for a variadic function

I'd like to wrap a variadic C++ function with a more modern C++11 style API.
The function is this one from the Pin instrumentation tramework:
VOID LEVEL_PINCLIENT::INS_InsertCall(INS ins,
IPOINT action,
AFUNPTR funptr,
...)
Where AFUNPTR is declared as:
typedef VOID (*AFUNPTR)();
and the ... is a list of arguments to pass funptr. The list is constructed of argument descriptors (IARG_TYPE enum), optional argument values, and a terminator IARG_END to denote the end of the list.
Here's a usage example for instrumenting a function before a given instructions (ins) that will print the contents of the rAX register:
void print_rax_and_tid(long rax, THREADID tid) {
cout << rax << endl << tid << endl;
}
...
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)print_rax_and_tid,
IARG_REG_VALUE, REG_RAX, // the value of rAX register
IARG_THREAD_ID, // the thread id
IARG_END)
Here we declare that our function will accept one argument that will hold a register value. We also request the tool to pass the value of the rAX register to the function.
Note that each function argument is described by one or two descriptors arguments:
(IARG_REG_VALUE, REG_RAX) describes (long rax)
(IARG_THREAD_ID) describes (THREADID tid)
The Pin framework sets the descriptors to know what to pass to the user function at runtime.
Also note that the type of the function arguments cannot be automatically deduced from the argument descriptors. In my example all the descriptors are enums, but they describe a long and THREADID argument.
I'd like to design this wrapper API with everything C++11 has to offer, possibly being able to pass a lambda instead of a function pointer, adding some type safety to the argument list, using variadic templates, etc.
Possibly the usage could look like this (but I'm open to suggestions):
INS_InsertCall(ins, IPOINT_BEFORE,
[](long rax, THREADID tid) { cout << rax << endl << tid << endl; },
IARG_REG_VALUE, REG_RAX,
IARG_THREAD_ID)
There's not really a whole lot I could think to do with that API: http://coliru.stacked-crooked.com/view?id=045edb71ffca8062a9e016506e4b51f7-4f34a5fd633ef9f45cb08f8e23efae0a
struct REG_VALUE {
IARG_TYPE arg = IARG_REG_VALUE;
REG_TYPE reg;
REG_VALUE(REG_TYPE r) :reg(r) {}
};
template<REG_TYPE reg_v>
struct REGISTER : REG_VALUE {
REGISTER() : REG_VALUE(reg_v) {}
};
template<class func_type, class ...param_types>
VOID InsertCall(INS ins, IPOINT action, func_type funptr,
param_types... param_values)
{ INS_InsertCall(ins, action, (AFUNPTR)funptr, param_values..., IARG_END); }
and then
InsertCall(ins, IPOINT_BEFORE, print_rax_and_tid,
REGISTER<REG_RAX>(), IARG_THREAD_ID);
I made the register a template type so you don't have to have the type/value pair, and then also made teh IARG_END automatic, but other than that, I don't understand enough of the API to understand what else could be automated.
You may use a template approach
#include <iostream>
template <typename Runnable, typename... Types>
auto execute(Runnable f, Types... ts) -> decltype(f(ts...))
{
return f(ts...);
}
// Some methods to test with:
void a() { std::cerr << __func__ << __LINE__ << "\n"; }
void b(int) { std::cerr << __func__ << __LINE__ << "\n"; }
void c(int, char) { std::cerr << __func__ << __LINE__ << "\n"; }
int d() { std::cerr << __func__ << __LINE__ << "\n"; return 0; }
int e(int) { std::cerr << __func__ << __LINE__ << "\n"; return 0; }
int f(int, char) { std::cerr << __func__ << __LINE__ << "\n"; return 0; }
int g() { std::cerr << __func__ << __LINE__ << "\n"; return 0; }
void g(int) { std::cerr << __func__ << __LINE__ << "\n"; }
int main()
{
int tmp = 1;
char tmp_2 = '0';
execute(a);
execute(b, tmp);
execute(c, tmp, tmp_2);
execute(d);
execute(e, tmp);
execute(f, tmp, tmp_2);
execute([](int){ std::cerr << __func__ << __LINE__ << "\n"; }, 0);
execute(b); // This won't compile, as too few arguments provided.
execute<int()>(g); // Explicit template instantiation needed (typename Runnable only)
execute<void(int)>(g, 0); // Explicit template instantiation needed (typename Runnable only)
}
If you want to discard the return value of your function, the template becomes even simpler
template <typename Runnable, typename... Types>
void execute(Runnable f, Types... ts)
{
f(ts...);
}
As you see, this works with lambdas too. If the function name is ambiguous, there is no way to avoid the explicit template instantiation.

C++ making a console: binding a function

I am currently working on creating a console in c++. I have created a class to help link variables and functions in code to variables and functions in the console.
I currently have it set where if I have a variable in code, I can redefine it under the new class and it will be visible to the console. The variable in code still behaves the same as before.
Example:
float var = 1.0;
can be redefined as
ConsoleVar var("myVariable")<float> = 1.0;
var is the variable name in the code and myVariable is the name that you use to access it in the terminal
My question is:
How can I bind a function, or more specifically, detect the number and type of the arguments.
I know that I can template the ConsoleVar class to a void * type to store a function but is there a way for me to auto detect the return type, number of arguments and type of arguments? I am planning on shipping this in a library so I am going for ease of use. If this is possible, I would really like to know (I'll even do assembly if needed) otherwise I have some ideas on how to implement it.
EDIT: So I think that I have a solution but I have a question... Is it possible to pass a variable number of arguments to a function. Not like varargs.
For instance: I recieve 3 args from the command line, now I execute the function
func(arg[1], arg[2], arg[3])
Is it possible to send a variable number of arguments?
This pattern will do the job.
#include <typeinfo>
// Function with 0 parameters
template< typename Ret >
void examine_function( Ret (*func)() )
{
std::cout << typeinfo(Ret).name() << std::endl;
}
// Function with 1 parameters
template< typename Ret, typename Param1 >
void examine_function( Ret (*func)(Param1) )
{
std::cout << typeinfo(Ret).name() << std::endl;
std::cout << typeinfo(Param1).name() << std::endl;
}
// Function with 2 parameters
template< typename Ret, typename Param1, typename Param2 >
void examine_function( Ret (*func)(Param1, Param2) )
{
std::cout << typeinfo(Ret).name() << std::endl;
std::cout << typeinfo(Param1).name() << std::endl;
std::cout << typeinfo(Param2).name() << std::endl;
}