4
typedef void int_void(int);

int_void is a function taking an integer and returning nothing.

My question is: can it be used "alone", without a pointer? That is, is it possible to use it as simply int_void and not int_void*?

typedef void int_void(int);
int_void test;

This code compiles. But can test be somehow used or assigned to something (without a cast)?


/* Even this does not work (error: assignment of function) */
typedef void int_void(int);
int_void test, test2;
test = test2;
Andreas Bonini
  • 44,018
  • 30
  • 122
  • 156
  • Have you tried actually compiling something like this? If so, what were the results? What was the actual source code? – FrustratedWithFormsDesigner Feb 19 '10 at 14:44
  • Like I said in the question, it compiles. The actual source code is this. Just wrap it in `int main()`. – Andreas Bonini Feb 19 '10 at 14:45
  • Notice that there is a restriction of what can be done with such a type. You are not allowed to use a dependent type for a function declaration that doesn't use the function declarator syntax: `template struct f { T g; } ... f s;` this is ill-formed rather than declaring a member function of type `void()`, because `T` is a dependent function type. – Johannes Schaub - litb Feb 19 '10 at 16:04

6 Answers6

7

What happens is that you get a shorter declaration for functions.

You can call test, but you will need an actual test() function.

You cannot assign anything to test because it is a label, essentially a constant value.

You can also use int_void to define a function pointer as Neil shows.


Example

typedef void int_void(int);

int main()
{
    int_void test; /* Forward declaration of test, equivalent to:
                    * void test(int); */
    test(5);
}

void test(int abc)
{
}
  • Thanks! That's a really cool way to confuse people! I added the testcase I wrote to make sure what you said actually worked, I hope you don't mind – Andreas Bonini Feb 19 '10 at 15:01
  • No, thank you. Alas, I can't figure a way to use it for the function itself, though. It would be cool to be able to eg. `pthread_entryfn a {` –  Feb 19 '10 at 15:08
  • 3
    It should be pointed out that the typedef can be used to declare a function, but it cannot be used to define the function, which is why in the example above the declaration of `test` and the definition look nothing alike. As far as I know, all other typedef'ed names can be used for both declaration and definition. – Michael Burr Feb 19 '10 at 15:13
  • 2
    @Andreas, not only it can confuse people, but also GCC: try `struct foo { void f(); }; typedef void ftype(); struct bar { friend ftype foo::f; };` and see GCC failing. – Johannes Schaub - litb Feb 19 '10 at 15:47
  • @Johannes: +1 even though if we had a +1 for every gcc bug we'd all be moderator gods.. ;-) – R.. GitHub STOP HELPING ICE Oct 19 '10 at 04:31
  • In particular, you can use it for a function template: `template int_void test;` – Johannes Schaub - litb Oct 19 '10 at 05:00
3

You are not declaring a variable; you are making a forward declaration of a function.

typedef void int_void(int);
int_void test;

is equivalent to

void test(int);
Jim Buck
  • 20,482
  • 11
  • 57
  • 74
2

It can be used in the following cases (out of the top of my head):

  • generic code:

    boost::function<int_void> func;

  • other typedefs:

    typedef int_void* int_void_ptr;

  • declarations:

    void add_callback(int_void* callback);

There may be others.

utnapistim
  • 26,809
  • 3
  • 46
  • 82
1

I think it's legal - the following demonstrates its use:

typedef void f(int);

void t( int a ) {
}

int main() {
    f * p = t;
    p(1); // call t(1)
}

and actually, this C++ code compiles (with g++) & runs - I'm really not sure how kosher it is though.

#include <stdio.h>

typedef void f(int);

void t( int a ) {
    printf( "val is %d\n", a );
}

int main() {
    f & p = t;   // note reference not pointer
    p(1);
}
  • Yes, I'm aware that you can use it as a pointer, but I specifically asked if it can be used without one :P (And, if not, why I can define a variable of that type) `My question is: can it be used "alone", without a pointer? That is, is it possible to use it as simply int_void and not int_void*?` – Andreas Bonini Feb 19 '10 at 14:53
  • @Andreas No. What would it mean? –  Feb 19 '10 at 14:54
  • It is definitely kosher. Shorter form of `void(&p)() = t;` – Johannes Schaub - litb Feb 19 '10 at 15:45
  • @Johannes But how come I can initialise a reference with a pointer? –  Feb 19 '10 at 15:51
  • @Neil, it's not a pointer but it's a function. The function-to-pointer conversion is done only when needed, like with arrays. As written, `t` is an lvalue and has type `void(int)`. – Johannes Schaub - litb Feb 19 '10 at 15:52
  • @Neil, see http://stackoverflow.com/questions/1516958/could-someone-please-explain-the-difference-between-a-reference-and-a-pointer/1517195#1517195 – Johannes Schaub - litb Feb 19 '10 at 16:12
  • @Johannes Thanks. Always good to learn something new - I don't think I've ever seen a function reference before, or maybe I just didn't notice them. –  Feb 19 '10 at 16:16
  • Another question about it: http://stackoverflow.com/questions/480248/function-references – Johannes Schaub - litb Feb 19 '10 at 16:23
0

Pointers to functions are values in C/C++. Functions are not.

yfeldblum
  • 65,165
  • 12
  • 129
  • 169
-1

This should work, no casting required:

void f(int x) { printf("%d\n", x); }

int main(int argc, const char ** argv)
{
    typedef void (*int_void)(int);
    int_void test = f;
    ...
 }

A function's name "devolves" into a function pointer anytime you use the function's name in something other than a function call. If is is being assigned to a func ptr of the same type, you don't need a cast.

The original

typedef int_void(int);

is not useful by itself, without using a pointer to the type. So the answer to your question is "no, you can't use that typedef without a pointer".

Tim Schaeffer
  • 2,616
  • 1
  • 16
  • 20