const function doesn't return char* - function

Can anyone explain me why if I make the function get_fName a const function, it returns _fName only with the casting (char*)? Without casting, it not compiles.
On the other hand, if I remove the const, it returns _fName also without casting?
class Student
{
int _id;
char _fName [20];
char* get_fName() const;
}
// implementation
char* Student::get_fName () const
{
return (char*)_fName;
}

What you're experiencing is the expected behaviour. When you declare a function const, you're effectively saying "this function will not modify the class' member variables". Thus, all the member variables to such a function appear as const. GCC emphasizes this in the error message :
x.cpp: In member function ‘char* Student::get_fName() const’:
x.cpp:11:12: error: invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]
return _fName;
^
This is because, to a const function, _fName appears to be a const char[20]. Conversion to a char[20], which would be modifiable, is not allowed unless you use a C-style cast or const_cast. When you don't declare the function const, _fName appears to be a char[20], which is implicitly convertible to char*, and the function works without casting.
However, this should not be done : if you need a function to modify the object's internals, simply don't declare it const, as it violates the contract you state that the function is making.
On another note, consider using std::string for storing strings in your program.

Related

Dart Functions as First Class Objects

int add(int n1,int n2) {
return n1+n2;
}
1.Function calc1=add;
2.Function calc2=(int n1,int n2) {
return n1+n2;
};
3.var calc3=(int n1,int n2)=>{
n1+n2
};
4.var callc=(int n1,int n2) {
return n1+n2;
};
Are all these doing the same thing?
In 1.Function calc1=add , is this pointing to the memory of add function or setting itself to the add function?
In 4. I am getting the error "The type of function literal can't be inferred because the literal has as block as it's body" but if I replace var keyword with Function then no error?Why?
These do slightly different things that may or may not act the same depending on how you use them.
1.
Function calc1 = add;
Declares a variable of type Function and assigns a reference to the add function to it.
If add is top-level, static or local variable, then all references to it is going to be the same value. If you refer an instance function (a method), you create a new closure every time.
2.
Function calc2=(int n1,int n2) {
return n1+n2;
};
Declares a variable with type Function, then evaluates a function literal to a function value. Each evaluation of that literal creates a new object.
3.
var calc3=(int n1,int n2)=>{
n1+n2
};
You probably meant to write
var calc3=(int n1,int n2)=>
n1+n2;
This is almost equivalent to 2. A body of => expression; is a shorthand for { return expression; }. However, you declare the variable as var, not Function, so type inference gives the variable the type int Function(int, int).
4.
var callc=(int n1,int n2) {
return n1+n2;
};
Completely equivalent to 3 if you do it as a local variable, but as a top-level variable, type inference does not look into the body to find the return type.
What you see is not an error, just a helpful info. I'm also not entirely sure it's correct. When I check the cpde in DartPad, it actually infers int Function(int, int) for var x = (int x, int y) { return x + y; };.
The biggest difference between the different cases in practice is that number 1 does not create a new closure each time it's evaluated, and that number 1 and 2 have type Function instead of int Function(int, int). That affects type checking, because Function allows any call to be made, while the precise function type only allows you to call the function with two integers (and knows that the result is an integer).

C++11: Why result_of can accept functor type as lvalue_reference, but not function type as lvalue_reference?

I've got program below:
#include<type_traits>
#include<iostream>
using namespace std;
template <class F, class R = typename result_of<F()>::type>
R call(F& f) { return f(); }
struct S {
double operator()(){return 0.0;}
};
int f(){return 1;}
int main()
{
S obj;
call(obj);//ok
call(f);//error!
return 0;
}
It fails to compile in the line of "call(f)".
It's weird that "call(obj)" is OK.
(1) I've a similar post in another thread C++11 result_of deducing my function type failed. But it doesn't tell why functor objects are OK while functions are not.
(2) I'm not sure if this is related to "R call(F& f)": a function type cannot declare a l-value?
(3) As long as I know, any token with a name, like variable/function, should be considered a l-value. And in the case of function parameter, compiler should "decay" my function name "f" to a function pointer, right?
(4) This is like decaying an array and pass it to a function----And a function pointer could be an l-value, then what's wrong with "call(F& f)"?
Would you help to give some further explanations on "why" is my case, where did I get wrong?
Thanks.
The problem with call(f) is that you deduce F as a function type, so it doesn't decay to a function pointer. Instead you get a reference to a function. Then the result_of<F()> expression is invalid, because F() is int()() i.e. a function that returns a function, which is not a valid type in C++ (functions can return pointers to functions, or references to functions, but not functions).
It will work if you use result_of<F&()> which is more accurate anyway, because that's how you're calling the callable object. Inside call(F& f) you do f() and in that context f is an lvalue, so you should ask what the result of invoking an lvalue F with no arguments is, otherwise you could get the wrong answer. Consider:
struct S {
double operator()()& {return 0.0;}
void operator()()&& { }
};
Now result_of<F()>::type is void, which is not the answer you want.
If you use result_of<F&()> then you get the right answer, and it also works when F is a function type, so call(f) works too.
(3) As long as I know, any token with a name, like variable/function, should be considered a l-value. And in the case of function parameter, compiler should "decay" my function name "f" to a function pointer, right?
No, see above. Your call(F&) function takes its argument by reference, so there is no decay.
(4) This is like decaying an array and pass it to a function----And a function pointer could be an l-value, then what's wrong with "call(F& f)"?
Arrays don't decay when you pass them by reference either.
If you want the argument to decay then you should write call(F f) not call(F& f). But even if you do that you still need to use result_of correctly to get the result of f() where f is an lvalue.

casting to const void* arguments on typdef function to use qsort in C

I have made the following typedefs in my program (C):
typedef void* ListElement;
typedef int(*CompareListElements)(ListElement, ListElement);
i have made a function pointer in my code:
CompareListElements compareElement
Later in the code i wish to use qsort on an array of ListElements:
qsort(elementsArray,listGetSize(list),sizeof(list->dummyHead->next->element, compareElement);
However the compiler states: "passing argument 4 of 'qsort' from incompatible pointer type".
I fear that it is because the qsort requires a function in the format of int (const void*, const void*). when i supply int (void*, void*).
Is there a way of casting the arguments of compareElement to (const void*, const void*), while calling qsort or before, WITHOUT changing the typedef?
Thanks
Simply cast the pointer to the appropriate type.
typedef int(*ConstCompareListElements)(const void *, const void *);
qsort(elementsArray,listGetSize(list),sizeof(list->dummyHead->next->element,
(ConstCompareListElements)compareElement);

how can i execute a host class function in a CUDA kernel

I have a genetic algorithm and i'm traying to evaluate a population of chromosome on GPU :
class chromosome
{
int fitness;
int gene(int pos) { .... };
};
class eval
{
public :
__global__ doEval(Chromosome *population)
{
....
int jobid = population[tid].gene(X);
population[tid].fitness = Z;
....
}
};
int main()
{
Chromosome *dev_population;
Eval eval;
eval.doEval<<<1,N>>>(dev_population);
}
and i have this errors :
ga3.cu(121): warning: inline qualifier ignored for "global" function
ga3.cu(121): error: illegal combination of memory qualifiers
ga3.cu(323): error: a pointer to a bound function may only be used to call the function
ga3.cu(398): warning: nested comment is not allowed
where are the problems ?
i remove Eval class and left only doEval function , and make device host gene() , like this :
\__device\__ \__host\__ gene()
{....};
\__global\__ doEval(Chromosome *population)
{
....
int jobid = population[tid].gene(X);
population[tid].fitness = Z;
....
}
int main()
{
Chromosome *dev_population;
doEval<<<1,N>>>(dev_population);
}
but now i have have other errors , and it's not compile :
/usr/include/c++/4.6/iomanip(66): error: expected an expression
/usr/include/c++/4.6/iomanip(96): error: expected an expression
/usr/include/c++/4.6/iomanip(127): error: expected an expression
/usr/include/c++/4.6/iomanip(195): error: expected an expression
/usr/include/c++/4.6/iomanip(225): error: expected an expression
5 errors detected in the compilation of "/tmp/tmpxft_00006fe9_00000000-4_ga3.cpp1.ii".
There are two problems here, one soluble, the other one not.
It is illegal in CUDA for a __global__ function (ie. kernel) to be defined as a class member function. So doEval can never be defined as a member of eval. You are free to call a kernel in a structure or class member function, but a kernel cannot be a member function. You will have to redesign this class, there is no work around.
Any function called device code must be explicitly denoted as a device function and be instantiated and compiled for the device. This applies to both regular functions and class member functions. All functions are treated by nvcc as host functions unless identified as otherwise. You can, therefore, fix this error by doing something like the following:
class chromosome
{
int fitness;
__device__ __host__ int gene(int pos) { .... };
};
Note that every function called by gene must also have a valid device definition for the code to successfully compile.

__cdecl wrapping WinSock function as callback in plain C and call it

Have prepared such function, where some WSA functions will be used as callback:
int StartWinSock(int (*WSAStartup)(WORD, LPWSADATA))
{
}
But when in other code, I'm trying to launch it:
StartWinSock(WSAStartup);
I'm getting an error:
'WSClient::StartWinSock' : cannot convert parameter 1 from 'int (__stdcall *)(WORD,LPWSADATA)' to 'int (__cdecl *)(WORD,LPWSADATA)'
Also, I don't know how to pass parameters correctly through callback function like WSAStartup() ( its parameters: WORD ( unsigned short number of version ) && LPWSADATA ( reference to WSAData ) ).
You are missing the __stdcall calling convention on the function pointer type, which comes from the WINAPI macro. The compiler is therefore assuming the default __cdecl calling convention for this pointer. The two calling conventions are not compatible.
Consider creating this typedef:
typedef int WINAPI (*WSAStartupCallback)(WORD, LPWSADATA);
Then declare your function like this:
int StartWinSock(WSAStartupCallback wsaStartup)
{
}
You should then be able to call this function with the external WSAStartup pointer.