I'm trying to print the return value of a templated member function in gdb (version 7.6.1 I think) of an rvalue reference, so what I write in gdb amounts to something like this:
gdb> print (*(TypeOne*)var).get<TypeTwo>()
I've tried parenthesizing various parts of the expression with no success, and I wasnt able to find any other question on this. Anyone know?
Starting from this related post: How to `print`/evaluate c++ template functions in gdb
I was able to figure out how to do this within my own program.
I'm not using an rvalue nor a variant so it may not work for that, but I think it's still relevant to this question.
My use case was a method with a single enum as a template parameter, similar to this:
#include <stdio.h>
enum class MyEnum {
VALUE_0 = 0,
VALUE_1 = 1
};
struct TestStruct {
template <MyEnum VALUE>
int getValue() {
if constexpr (VALUE == MyEnum::VALUE_0) {
return value_0;
} else /* VALUE == MyEnum::VALUE_1 */ {
return value_1;
}
}
const int value_0 = 7;
const int value_1 = 9;
};
int main()
{
TestStruct test;
test.template getValue<MyEnum::VALUE_0>();
test.template getValue<MyEnum::VALUE_1>();
return 0;
}
If we use ptype on the object we get a list of methods on the object:
(gdb) b 36
Breakpoint 1 at 0x4004f7: file main.cpp, line 36.
(gdb) r
Starting program: /home/a.out
Breakpoint 1, main () at main.cpp:36
36 return 0;
(gdb) ptype test
type = struct TestStruct {
const int value_0;
const int value_1;
public:
int getValue<(MyEnum)1>(void);
int getValue<(MyEnum)0>(void);
}
If we want to call this method:
int getValue<(MyEnum)1>(void);
We can call it by using the name exactly as shown, in single quotes.
(gdb) p test.'getValue<(MyEnum)1>'()
$1 = 9
You can try it here: https://onlinegdb.com/7OtaUvK3g
Note from the other thread:
Without an explicit instance in the source code, the compiler will treat the template code as it would "static inline" code and optimize it out if it is unused.
So you must call the method somewhere in your code to be able to call it in gdb at all, this will not work otherwise.
Related
I am trying to pass parameters to a function pointer being passed as a parameter.
Code:
void Test(wchar_t* a, wchar_t* b)
{
// ...
}
void Test2(void(*Func)(wchar_t*, wchar_t*))
{
// ...
}
int main()
{
Test2(Test(L"Hello", L"Testing"));
return 0;
}
I am getting this error:
argument of type "void" is incompatible with parameter of type "void (*)(wchar_t *, wchar_t *)"
How do I fix this to accomplish what I'm trying to achieve?
Edit: Sorry for not being clear. What I'm actually trying to accomplish is inject a function into a child process and pass two parameters (wchar_t*, wchar_t*) so I can use them. But the main function can either be void or int argc, char** argv. So I accomplished what I'm trying to achieve by simply using global variables
You probably want to have something like
void Test2(void(*Func)(wchar_t*, wchar_t*),wchar_t* x, wchar_t* y)
{
(*Func)(x,y);
}
int main()
{
Test2(Test,L"Hello", L"Testing");
return 0;
}
instead.
As for your comment
How do i do this in C++ with templates?
I could think of
template<typename Param>
void Test2(void(*Func)(Param, Param), Param x, Param y) {
(*Func)(x,y);
}
void Test(wchar_t* a, wchar_t* b);
int main() {
Test2(Test,L"Hello", L"Testing");
return 0;
}
This should just work fine.
There are more than one way to fix tihs issue, however, let me just try to show why this error is occuring.
Every function has a type of value associated with it. This means, that every function evaluates to a value of some type. This is indicated by its return value.
For example:
int foo(/*whatever*/);
evaluates to an int. So foo(/*whatever*/) can be used anywhere an int is expected. For example like int a = b + foo(/*whatever*/).
Simlarly float bar(/*whatever*/); evaluates to a float, hence bar(/*whatever*/) can be used anywhere a float is expected. For example like float a = b + bar(/*whatever*/).
A function that returns void like void foobar(/*whatever*/) however, evaluates to void and cannot be used where a value of some type (say int, float, etc) is expected.
Now coming to code. This line in your main function has the issue:
int main()
{
Test2(Test(L"Hello", L"Testing")); /* Issue here */
return 0;
}
Here you are passing Test(L"Hello", L"Testing") as the argument to Test2. Now remember, that Test(/*whatever*/), evaluates to a void because Test returns a void.
So what you are doing in that line is something like
Test2(/*something that evaluates to a void*/);
However, Test2 expectes a void (*)(wchar_t*, wchar_t*), which is a pointer to a function that returns void, which is different from void.
So what is happening, is that the compiler is seeing that you are passing a void in a place where a void (*) (wchar_t*, wchar_t*) is expected, so it is correctly indicating that error.
There can be different ways to solve this issue which are mentioned in other answers.
Do I need to use C++ templates?
Of course, you can do that using C++ templates as it follows:
#include<utility>
// ...
template<typename F, typename... A>
void Test2(F &&f, A&&... a)
{
std::forward<F>(f)(std::forward<A>(a)...);
// ...
}
// ...
Test2(Test, L"Hello", L"Testing");
But you don't need them to do what you are trying to do.
#πάνταῥεῖ has already explained why in its answer.
Consider the following program, which I compile with g++ -g myprog.cc.
#include<iostream>
struct Context {
//char *s; // version 1
std::string s; // version 2
};
void f(Context);
void f(Context c) {}
int main(void) {
Context c = Context();
f(c);
}
Version 1 has a char * member, while version 2 replaces it with std::string.
Using gdb, I step through the code and get this:
Temporary breakpoint 1, main () at myprog.cc:12
12 Context c = Context();
&ebsp;Missing separate debuginfos, use: debuginfo-install libgcc-4.4.7-11.el6.x86_64 libstdc++-4.4.7-11.el6.x86_64
(gdb) s
13 f(c);
(gdb) s
f (c=...) at myprog.cc:9
9 void f(Context c) {}
(gdb) s
main () at myprog.cc:14
14 }
Nothing wrong here.
If I step through version 2, I get:
Temporary breakpoint 1, main () at myprog.cc:12
12 Context c = Context();
Missing separate debuginfos, use: debuginfo-install libgcc-4.4.7-11.el6.x86_64 libstdc++-4.4.7-11.el6.x86_64
(gdb) s
Context::Context (this=0x7fffffffe400) at myprog.cc:3
3 struct Context {
(gdb) s
main () at myprog.cc:13
13 f(c);
(gdb) s
Context::Context (this=0x7fffffffe410) at myprog.cc:3
3 struct Context {
(gdb) s
f (c=...) at myprog.cc:9
9 void f(Context c) {}
(gdb) s
Context::~Context (this=0x7fffffffe410, __in_chrg=) at myprog.cc:3
3 struct Context {
(gdb) s
Context::~Context (this=0x7fffffffe400, __in_chrg=) at myprog.cc:3
3 struct Context {
(gdb) s
main () at myprog.cc:14
14 }
Why is it that when I pass in a struct Context with the std::string member, I get the output Context::Context (this=0x7fffffffe400)?
Also, when I instantiate the struct, this=0x7fffffffe400. When I pass it in, this=0x7fffffffe410. Why is that?
You pass c by value to a function that doesn't do anything. So the compiler has to produce any visible effects of pass by value semantics. The compiler can't be sure that copying and then destroying the string has no consequences, so it does it. It can be sure that copying a char * and destroying the copy has no consequences, so it doesn't bother.
What's happening is you're seeing the compiler generated constructor, which is not generated for the struct with just a pointer, because there would be nothing to do in that constructor. For the struct with the std::string member, it likely calls std::strings constructor.
Since the constructor is a non-static member function, the this=0x7fffffffe400 is the implicit 'this' pointer argument being passed in.
When I define a function of a class, I call another function of the same class within it. But when I do not type the class name it gives segmentation fault. Check below.
Header file
class DomainSolver
{
int fnc1 (UserDefinedType & var);
int fnc2 (UserDefinedType & var);
};
C file
int DomainSolver::fnc2 (UserDefinedType & var)
{
return 0;
}
int DomainSolver::fnc1 (UserDefinedType & var)
{
// fnc2 (var); // does not work
DomainSolver::fnc2(var); // works
return 0;
}
Wild guess… since the code you presented does not have any issues…
The function being called is declared virtual in a base class, so even if the virtual keyword is not present in the declaration here it is virtual.
The function being called does not access any member of the object.
You are calling the function on an invalid pointer or reference (for example through a null pointer or on an object that has already been deleted.
If all those guesses are right, the use of the qualification inhibits the dynamic dispatch mechanism, avoiding the dereference of an invalid pointer to the vtable. The code is still wrong (due to the third point above), but it seems to work.
The solution is not to call a member function through an invalid pointer or reference.
Although as pointed out by Zac's reply, the functions as you present them are not properly formed, there shouldn't be a difference between calling the scoped version; if you are getting a segfault in one case and not the other it's possibly because of code elsewhere.
Here is an example that works just fine:
dsolver.hh
#ifndef DSOLVER_HH
#define DSOLVER_HH
class DomainSolver
{
public:
int fnc1 (int& var);
int fnc2 (int& var);
};
#endif
dsolver.cc
#include <iostream>
#include "dsolver.hh"
int DomainSolver::fnc1 (int& var)
{
std::cout << "fnc1\n";
fnc2( var );
var = -1;
return var;
}
int DomainSolver::fnc2 (int& var)
{
std::cout << "fnc2\n";
var = 100;
return var;
}
main.cc
#include <iostream>
#include "dsolver.hh"
int main()
{
DomainSolver my_dsolver;
int my_int = 5;
my_dsolver.fnc1(my_int);
return 0;
}
Assuming this is close to your actual code, you have undefined behavior in fnc1:
int DomainSolver::fnc1 (UserDefinedType & var)
{
// fnc2 (var); // does not work
DomainSolver::fnc2(var); // works
// missing return!!!
}
You declare it to return an int, but then never return anything (in either case). Both cases are UB, so anything they do is technically "valid", since your code is not.
This code should be:
int DomainSolver::fnc1 (UserDefinedType & var)
{
return fnc2 (var);
}
As a side note: This is a good example of why you should never ignore the warnings given by the compiler (as you should have received a warning with both versions).
EDIT
With your latest edit adding a return value to fnc1, you'll need to show more of your actual code as there is not enough there to properly diagnose the problem (with the return being there, there is nothing wrong with your shown code).
I have a class Test with a peculiar data structure.
A member of class Test is a std::map where the key is a std::string and the mapped value is a struct defined as follows:
typedef struct {
void (Test::*f) (void) const;
} pmf_t;
Initialization of the map is OK. The problem is when I am trying to call the function pointed. I made up a toy example reproducing the problem. Here it is:
#include <iostream>
#include <map>
using namespace std;
class Test;
typedef void (Test::*F) (void) const;
typedef struct {
F f;
} pmf_t;
class Test
{
public:
Test () {
pmf_t pmf = {
&Test::Func
};
m["key"] = pmf;
}
void Func (void) const {
cout << "test" << endl;
}
void CallFunc (void) {
std::map<std::string, pmf_t>::iterator it = m.begin ();
((*it).second.*f) (); // offending line
}
std::map<std::string, pmf_t> m;
};
int main ()
{
Test t;
t.CallFunc ();
return 0;
}
Thanks in advance,
Jir
The name of the pmf_t type is f, so the first change is to remove the * to get second.f. That gives you a pointer-to-member value. To use a pointer-to-member, you need an instance. The only one you have available of the correct type is this, so use it with the ->* operator:
(this->*it->second.f)();
You need parentheses around the whole thing, or else the compiler thinks you're trying to call it->second.f() (which isn't allowed) and then applying the result to ->*.
The offending line is trying to call a member function without any object to call it on. If the intention is to call it for the this object, I believe the call should look like
( this->* ((*it).second.f) )();
Where this->* is the syntax for dereferencing a pointer-to-member for the current object. ((*it).second.f) is the pointer retrieved from the map, and () is the call operator for actually calling the function.
This is perhaps good as an exercise, but otherwise of limited use.
I think you might want to check out the C++ FAQ on this one. The syntax is apparently pretty tricky to get right (they actually recommend using a macro).
It might be too late for this question but, the seemingly complex synatax can be break down to two simple lines so it looks pretty clear:
void CallFunc (void)
{
pmf_t t = m["key"]; //1>get the data from key
(this->*t.f)(); //2>standard procedure to call pointer to member function
}
try this:
(this->*((*it).second.f)) ();
Could someone please tell me if this is possible in C or C++?
void fun_a();
//int fun_b();
...
main(){
...
fun_a();
...
int fun_b(){
...
}
...
}
or something similar, as e.g. a class inside a function?
thanks for your replies,
Wow, I'm surprised nobody has said yes! Free functions cannot be nested, but functors and classes in general can.
void fun_a();
//int fun_b();
...
main(){
...
fun_a();
...
struct { int operator()() {
...
} } fun_b;
int q = fun_b();
...
}
You can give the functor a constructor and pass references to local variables to connect it to the local scope. Otherwise, it can access other local types and static variables. Local classes can't be arguments to templates, though.
C++ does not support nested functions, however you can use something like boost::lambda.
C — Yes for gcc as an extension.
C++ — No.
you can't create a function inside another function in C++.
You can however create a local class functor:
int foo()
{
class bar
{
public:
int operator()()
{
return 42;
}
};
bar b;
return b();
}
in C++0x you can create a lambda expression:
int foo()
{
auto bar = []()->int{return 42;};
return bar();
}
No but in C++0x you can http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions which may take another few years to fully support. The standard is not complete at the time of this writing.
-edit-
Yes
If you can use MSVC 2010. I ran the code below with success
void test()
{
[]() { cout << "Hello function\n"; }();
auto fn = [](int x) -> int { cout << "Hello function (" << x << " :))\n"; return x+1; };
auto v = fn(2);
fn(v);
}
output
Hello function
Hello function (2 :))
Hello function (3 :))
(I wrote >> c:\dev\loc\uniqueName.txt in the project working arguments section and copy pasted this result)
The term you're looking for is nested function. Neither standard C nor C++ allow nested functions, but GNU C allows it as an extension. Here is a good wikipedia article on the subject.
Clang/Apple are working on 'blocks', anonymous functions in C! :-D
^ ( void ) { printf("hello world\n"); }
info here and spec here, and ars technica has a bit on it
No, and there's at least one reason why it would complicate matters to allow it. Nested functions are typically expected to have access to the enclosing scope. This makes it so the "stack" can no longer be represented with a stack data structure. Instead a full tree is needed.
Consider the following code that does actually compile in gcc as KennyTM suggests.
#include <stdio.h>
typedef double (*retdouble)();
retdouble wrapper(double a) {
double square() { return a * a; }
return square;
}
int use_stack_frame(double b) {
return (int)b;
}
int main(int argc, char** argv) {
retdouble square = wrapper(3);
printf("expect 9 actual %f\n", square());
printf("expect 3 actual %d\n", use_stack_frame(3));
printf("expect 16 actual %f\n", wrapper(4)());
printf("expect 9 actual %f\n", square());
return 0;
}
I've placed what most people would expect to be printed, but in fact, this gets printed:
expect 9 actual 9.000000
expect 3 actual 3
expect 16 actual 16.000000
expect 9 actual 16.000000
Notice that the last line calls the "square" function, but the "a" value it accesses was modified during the wrapper(4) call. This is because a separate "stack" frame is not created for every invocation of "wrapper".
Note that these kinds of nested functions are actually quite common in other languages that support them like lisp and python (and even recent versions of Matlab). They lead to some very powerful functional programming capabilities, but they preclude the use of a stack for holding local scope frames.
void foo()
{
class local_to_foo
{
public: static void another_foo()
{ printf("whatevs"); }
};
local_to_foo::another_foo();
}
Or lambda's in C++0x.
You can nest a local class within a function, in which case the class will only be accessible to that function. You could then write your nested function as a member of the local class:
#include <iostream>
int f()
{
class G
{
public:
int operator()()
{
return 1;
}
} g;
return g();
}
int main()
{
std::cout << f() << std::endl;
}
Keep in mind, though, that you can't pass a function defined in a local class to an STL algorithm, such as sort().
int f()
{
class G
{
public:
bool operator()(int i, int j)
{
return false;
}
} g;
std::vector<int> v;
std::sort(v.begin(), v.end(), g); // Fails to compile
}
The error that you would get from gcc is "test.cpp:18: error: no matching function for call to `sort(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, f()::G&)'
"
It is not possible to declare a function within a function. You may, however, declare a function within a namespace or within a class in C++.
Not in standard C, but gcc and clang support them as an extension. See the gcc online manual.
Though C and C++ both prohibit nested functions, a few compilers support them anyway (e.g., if memory serves, gcc can, at least with the right flags). A nested functor is a lot more portable though.
No nested functions in C/C++, unfortunately.
As other answers have mentioned, standard C and C++ do not permit you to define nested functions. (Some compilers might allow it as an extension, but I can't say I've seen it used).
You can declare another function inside a function so that it can be called, but the definition of that function must exist outside the current function:
#include <stdlib.h>
#include <stdio.h>
int main( int argc, char* argv[])
{
int foo(int x);
/*
int bar(int x) { // this can't be done
return x;
}
*/
int a = 3;
printf( "%d\n", foo(a));
return 0;
}
int foo( int x)
{
return x+1;
}
A function declaration without an explicit 'linkage specifier' has an extern linkage. So while the declaration of the name foo in function main() is scoped to main(), it will link to the foo() function that is defined later in the file (or in a another file if that's where foo() is defined).