C ­function declaration in a parameter list - c++

I'm find out a bit confusing thing in C code
struct SomeStruct {
// ...
void (*f)(const void *x);
};
void do_some( void f(const void *x) ) { // what?
struct SomeStruct* v;
// ...
v->f = f;
}
As I can understand do_some take function instead function pointer.
But what is difference with void do_some( void (*f)(const void *x) ) in practice? When I should use this? Is this allowed in C++?

There is no difference. It's just syntactic sugar. It is allowed in both C and C++.
Function parameters are simply rewritten by the compiler as function pointer parameters, just as array parameters are rewritten by the compiler as pointer parameters.
For reference, here is an excerpt from the C standard, section 3.7.1:
g(int (*funcp)(void))
// ...
or, equivalently,
g(int func(void))

As I can understand do_some take function instead function pointer.
No, as a function parameter a function type is adjusted to the corresponding function pointer type. The argument f has the same function pointer type as the member f.
But what is difference with void do_some( void (*f)(const void *x) ) in practice?
None whatsoever.
When I should use this?
If you like extra verbosity. Or in other contexts, such as declarations, where you need to distinguish function and pointer types.
Is this allowed in C++?
For function parameters (and also non-type template parameters) the same adjustment is applied in C++.

Related

Omit void as function result in C++

In C/C++ there are two ways to declare a function that returns nothing.
First one is to declare a function without arguments:
// no arguments
void f() {
}
The second one is to declare a function that takes void:
// still no arguments
void f(void) {
}
However, this is not true for the function result: we can't omit void at the beginning of the function like this:
// returns nothing
f() {
return; // yay
}
So, is there absolutely no way to omit void at the beginning of the function like with the function arguments?
So, is there absolutely no way to omit void at the beginning of the function like with the function arguments?
No, there absolutely isn't. There is no function declaration syntax that doesn't have the return type in C++ nor in C99 or later. There used in C prior to C99, but the default return type would have been int rather than void.
Note that declarations void f() and void f(void) are not equivalent in C. Former declares a function with unspecified parameters while the latter declares a function with empty parameter list. In C++, both declare a function with empty parameter list.

Why can't void parameters exist in functions with more than one argument?

I "wanted" to use void as a placeholder (or overload disambiguator) or even as a shortcut to have functions with void return type called before entering a specific function like in the following example:
int f(void , int)
{
return 0;
}
void g()
{
}
int main()
{
f(g(), 1);
}
Now, this is not a real world problem (I know that I could just call g() before calling f()) but I was wondering why this is not doable, especially when I can e.g. explicitly return void types i.e. this is legal :
void h()
{
return g(); // this does a return void
}
EDIT
To explain the rationale behind asking this, I first thought that according to C legacy, void would be an incomplete type, so incomplete types cannot appear as function parameters, unlike pointers to incomplete types and hence the void* commonality. Now this would explain void as a "special case" signal for "no parameters" but after C++11 the Standard reads (3.9 [basic.types]) :
A type is a literal type if it is:
void; or
a scalar type; or
....
Being a literal type, I can't find elsewhere any rationale that would exclude void from candidate types for function parameters, neither the equivalent of old C's (prior to C11) "void is not a type". Now, my search may be lacking the required depth which is what I try to compensate for in this Q
A void parameter means the function has no parameters*. It wouldn't make much sense for a function with no parameters to have some parameters.
* This is inherited from C (and presumably kept for compatibility with that language), where a function declared without a parameter list is a function that can take any number of parameters of any type. In C++, such a function would have no parameters, removing the need to use void parameters.
The only real problem here is your function prototype:
int f(void , int)
You cannot give a void as a parameter. You can set it as a return value, meaning "this function returns nothing", or you can give it as only parameter, like this:
int f(void)
It would means "this function takes no parameter", but not as a parameter.
But to give a parameter of void type would mean you could declare a void variable and give it to your function, which would have no sense.
In your sample:
void h()
{
return g(); // this does a return void
}
This does not a return void. This does return nothing. This is as legal as:
void h()
{
return;
}
So here, you can clearly see void is just a meaning of nothing.
Try to use functions returning void as arguments, like you did:
f(g(), 1);
Should be avoided as much as possible.
I've wanted a void argument type in order to have a parameter that is zero-cost in release builds:
#ifdef NDEBUG
typedef DebugTracker* Foo;
#else
typedef void Foo;
#endif
int SomeFunction(Foo foo, ...) {
...
}
I can't find elsewhere any rationale that would exclude void from candidate types for function parameters
#juanchopanza has pointed out one thing, which is that C++ inherited C's f(void) meaning a function that takes no arguments. That being so, C++ still could have the feature but make void parameters act as if they had a default value of nothing...so having such a default if they were at the end of argument lists.
In language-design space, it's always easy to think of the case you have in mind and say "why not?". And if you look at something like libffi then it seems like prohibiting void for arguments makes the system less "pure". There's a count of bytes for each argument, how hard would it be to allow 0?
But there are questions to answer.
If void parameters are possible, then that posits the existence of void variables. How does a void variable act? What's its address? If you can't take the address of a void variable, how does that impact the compiler...the linker...what's going to happen with name-mangling, etc.
I don't know enough to tell you if the pretzel of the existing C and C++ standard can be untwisted in a way that void parameters do more good than harm. It would be an interesting study to take a compiler and some large body of code and think through the details. I upvoted the question as reasonable to ask, but also voted to close as primarily opinion-based, so... that's my 0.02.

difference between void(int) & void (*)(int)

I know void (*)(int) is to function pointer but what is void(int)?
It's used for std::function template.
Say I have a function void fun(int){} : decltype(&fun) gives void(*)(int) but decltype(fun) gives void(int)
If T is a type, then T* denotes the type "pointer-to-T".
The type void(int) is a function type, it's the type of a function taking one int and returning void. For example, it is the type of f if f is declared as void f(int);
If T = void(int), then T* is spelled void(*)(int), so the latter is the type of a function pointer. You can also form a reference to a function, which is T& = void(&)(int); this is occasionally more useful (e.g. you can take the address of a function lvalue).
Aside note: Function lvalues decay to their function pointer very easily. You can call a function either via a function lvalue or via a function pointer. When used as an operand for the indirection operator (*), the function value decays, so you can dereference the pointer again and again:
printf("Hello world\n"); // OK
(*printf)("Hello world\n"); // also OK
(****printf)("Hello world\n"); // four-star programmer
Some of the only times that a function does not decay is when used as the operand of the address-of operator, or when bound to a reference:
void f(int); // our example function
void(*p1)(int) = &f; // no decay of "f" here
void(*p2)(int) = f; // "f" decays
void(&r1)(int) = f; // no decay of "f" here
void g(void(&callback)(int), int n) {
callback(n);
}
g(f, 10); // no decay of "f" here
template <typename F, typename ...Args>
decltype(auto) h(F&& callback, Args&&... args) {
return std::forward<F>(callback)(std::forward<Args>(args)...);
}
h(f, 10); // no decay of "f" here
void (*whatever)(int)
should be read as: whatever is a pointer, pointing to a function, that accepts one int as argument, and returns nothing (ie., void).
void whatever(int)
should be read as: whatever is a function (NOT a pointer), that accepts one int as argument, and returns nothing (ie., void)
Once the pointer to a function is initialized to point to a valid function (one that satisfies the prototype), then you can invoke the function either through its "real" name, or through the pointer.
Pointers to functions are very useful - they're variables, just like anything else, so you can pass them around to other functions (see e.g. qsort()), you can put them in structs, etc..
Given this, the following code is valid:
#include <stdio.h>
void myfun(int x) {
printf("The value of X is %d\n", x);
}
int main() {
void (*myfunp)(int);
myfunp = &myfun;
myfun(13);
myfunp(12);
return 0;
}
void(*)(int) should be read as type of a pointer which is pointing to a function, that accepts one int as argument, and returns nothing.
For understanding more on function to pointer and its usage please check here: http://www.cprogramming.com/tutorial/function-pointers.html

Do I have to specify a '*' before function pointer?

When I'm passing function as parameter to other functions in c++ , do I have to specify it as
void callOtherFunctions(void f());
or
void callOtherFunctions(void (*f)());
I have no idea what happens under the hood , so I tried running both versions with a simple program as below , replacing the necessary part for 2nd run.
#include <iostream>
using namespace std;
void printHello();
void callOtherFunctions(void f());
int main() {
callOtherFunctions(printHello);
return 0;
}
void printHello(){
std::cout<<"\n Hello World";
}
void callOtherFunctions(void f()){
for (int i=0;i<5;++i){
f();
}
}
and to my surprise , both execute with same output and no warnings. So which is the preferred way , or correct way ( in case I'm doing something wrong ). And what actually happens in each case , when I pass pointer - does it executes address function there and when I pass function - does it copies down whole function there? or something else?
Here is Ideone Link
void callOtherFunctions(void f());
and
void callOtherFunctions(void (*f)());
are identical. Quoting N1570,
§6.7.6.3/8 A declaration of a parameter as "function returning type"
shall be adjusted to "pointer to function returning type", as in
6.3.2.1.
I would prefer the function pointer syntax because more people would be familiar with it and it's explicit what you mean. To answer your second question, a conversion also happens in certain cases (informally known as "decay"):
§6.3.2.1/4 A function designator is an expression that has function
type. Except when it is the operand of the sizeof operator, the
_Alignofoperator,65) or the unary & operator, a
function designator with type "function returning type" is converted to an expression that has type "pointer to function returning type".
Function parameter declarations are somewhat unusual; the compiler will adjust some of the declared types. This is one of them: function parameters of function type are adjusted to the corresponding pointer type.
Other common adjustments to function parameters are array to pointer type, and removing top-level const:
int foo(int a[5]); // a is a pointer
int foo(const int a); // foo() can be called with a non-const int argument.

C++ -- Questions about function pointers

I have written the following code:
#include "stdafx.h"
#include <iostream>
using namespace std;
double funcA()
{
return 100.0;
}
int g(double (*pf)())
{
cout << (*pf)() << endl;
return 0;
}
int g2(double pf())
{
cout << pf() << endl;
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
g(&funcA); // case I
g(funcA); // case II
g2(funcA); // case III
g2(&funcA); // case IV
return 0;
}
I have run the above code on VS2008 and each function call returns '100'.
Here is the question:
Q1> Is there any problem in the code?
Q2> It seems that C++ doesn't make difference between *pf and pf. Is that correct?
Thank you
C++ does, in fact, make a distinction between the types double() and double(*)(), but the difference is subtle. When you pass a function type as an argument to a function, the function-type automatically "degrades" to a function pointer. (This is similar, I suppose, to how an array type degrades to a pointer type when passed as a function argument.)
However, a function type and a function-pointer type are still different types, according to the C++ type-system. Consider the following case:
void g() { }
template <class F>
struct Foo
{
Foo(const F& f) : func(f)
{ }
void operator()() { func(); }
F func;
};
int main ()
{
Foo<void()> f(g);
f();
}
This should fail to compile, since you cannot declare a function type as an automatic variable. (Remember, functions are not first-class objects in C++.) So the declaration F func; is invalid. However, if we change our main function to instead instantiate the template using a function pointer, like so:
int main ()
{
typedef void(*function_pointer)();
Foo<function_pointer> f(g);
f();
}
...now it compiles.
The following functions are identical:
int g(double (*pf)())
{
cout << (*pf)() << endl;
return 0;
}
int g2(double pf())
{
cout << pf() << endl;
return 0;
}
Dereferencing a function pointer (as shown in g) is the same as calling that function's name.
Q2> It seems that C++ doesn't make
difference between *pf and pf. Is that
correct?
There is a difference between *pf and pf (as variables). If pf is a function, *pf and pf() are identical (Note the parentheses).
With most modern compilers, there is no difference between "(*variable)." and "variable->". However, one must check the class in use to see if it overrides the dereference operator.
Many programmers use typedef when defining function pointers, primarily to make reading easier. Also, the double pf() syntax may be prone to readability errors and can get confused with executing a function on parameter line.
There's no problem or difference in the code you posted. However, if you are writing templates which take functors, you should use the syntax in g2. Consider the following:
template<typename Iter, typename Func>
void for_each(Iter begin, Iter end, Func functor)
{
for(; begin != end; ++begin)
{
functor(*begin);
}
}
Note that if you put the dereference operator before functor, you limit the utility of the algorithm you have written to function pointers. However, if you don't put that there, someone can pass an STL functor, such as something returned by std::bind2nd.
Therefore I would overall recommend using the second (without *) syntax where possible.
Consider the following piece of code
void pf();
void (&prf)() = pf; // OK, bind prf to pf
void (&prf)() = &pf; // ill-formed, can't bind prf to an function pointer value
On the other hand
void (*ppf)() = pf; // OK, function decays to a pointer
void (*ppf)() = &pf; // OK, pointer assigned to a pointer
So there is an implicit conversion from a function to a pointer (which is called "decay"). This also makes you able to say ***...***pf - arbitrarily many times dereference it - in each step a function to pointer conversion occurs which undoes the effect of the previous dereference.
In function parameter lists, a T f() and a T (*f)() are equivalent ways (except for spelling) of declaring a parameter
void f(void g()); // g has type void (*)()
void f(void (*g)()); // g has type void (*)()
A reference will inhibit this parameter type adjustment
void f(void (&g)()); // g has *not* the type void (*)()
This is exactly the same as for array declared parameters: Parameters are never arrays, but they will always be pointers, if they were declared as being arrays.