77

In a C++ reference page they provide some typedef examples and I'm trying to understand what they mean.

// simple typedef
typedef unsigned long mylong;


// more complicated typedef
typedef int int_t, *intp_t, (&fp)(int, mylong), arr_t[10];

So the simple typedef (the first declaration) I understand.

But what are they declaring with the second one (repeated below)?

typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10];

Particularly what does (&fp)(int, mylong) mean?

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
rsgmon
  • 1,892
  • 4
  • 23
  • 35
  • 47
    It should be noted that writing a one-liner typedef goo like this is very bad programming practice, because it is hard to read and there is no advantage whatsoever from it. So if you are reading this and have never seen typedefs like this, please don't start using this syntax. – Lundin Feb 27 '14 at 07:35
  • 3
    @Lundin I disagree. Putting them all on one line makes it clear that you intent to have them all refer to the same base type. By definition. – Mr Lister Feb 27 '14 at 10:53
  • 9
    @MrLister If you write them each at a separate line after each other, each line will start with `typedef some_type ...` and you have several lines like that, your intentions are very clear and there's no room for syntax slips. Far more readable. – Lundin Feb 27 '14 at 13:45
  • 2
    @Lundin It may be a matter of taste, so I'm not sure if we need to go into a discussion about this. – Mr Lister Feb 27 '14 at 14:02

5 Answers5

96

It's declaring several typedefs at once, just as you can declare several variables at once. They are all types based on int, but some are modified into compound types.

Let's break it into separate declarations:

typedef int int_t;              // simple int
typedef int *intp_t;            // pointer to int
typedef int (&fp)(int, ulong);  // reference to function returning int
typedef int arr_t[10];          // array of 10 ints
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 5
    Throughout my years of programming C++ I did not know that! I guess my instructor did not believe it was necessary to learn that and I never found anything about it. +1 – John Odom Feb 27 '14 at 14:51
  • 17
    Your instructor was right. This is harder to read, it's a feature you *shouldn't* use. – Plutor Feb 27 '14 at 22:46
42
typedef int int_t, *intp_t, (&fp)(int, mylong), arr_t[10];

is equivalent to:

typedef int int_t;
typedef int *intp_t;
typedef int (&fp)(int, mylong);
typedef int arr_t[10];

There is actually a similar example in the C++11 standard:

C++11 7.1.3 The typedef specifier

A typedef-name does not introduce a new type the way a class declaration (9.1) or enum declaration does.Example: after

typedef int MILES , * KLICKSP ;

the constructions

MILES distance ;
extern KLICKSP metricp ;

are all correct declarations; the type of distance is int that of metricp is “pointer to int.” —end example

Community
  • 1
  • 1
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
32

If you have the cdecl command, you can use it to demystify these declarations.

cdecl> explain int (&fp)(int, char)
declare fp as reference to function (int, char) returning int
cdecl> explain int (*fp)(int, char)
declare fp as pointer to function (int, char) returning int

If you don't have cdecl, you should be able to install it in the usual way (e.g. on Debian-type systems, using sudo apt-get install cdecl).

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Amarghosh
  • 58,710
  • 11
  • 92
  • 121
0

The (&fp)(int, mylong) part represents a reference to a function. It is not recommended that programmers use functions in typedef for the very reason you're asking this question. It confuses other people looking at the code.

I'm guessing they use the typedef in something like this:

typedef unsigned long mylong; //for completeness
typedef int (&fp)(int, mylong);
int example(int param1, mylong param2);

int main() {
     fp fp_function = example;
     int x = fp_function(0, 1);
     return 0;
}

int example(int param1, mylong param2) {
     // does stuff here and returns reference
     int x = param1;
     return x;
}

Edited in accordance with Brian's comment:

int(&name)(...) is a function reference called name (the function returns an int)

int &name(...) is a function called name returning a reference to an int

A reference to a function which returns an int reference would look something like this: typedef int &(&fp)(int, mylong) (this compiles in a program, but the behaviour is untested).

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
SameOldNick
  • 2,397
  • 24
  • 33
  • 3
    No, `int&(int, mylong)` is a different type from `int(&)(int, mylong)`. The former is a function returning a reference to `int`. The latter is a reference to a function returning `int`. References to functions are obscure and not very useful, but they do exist in C++. – Brian Bi Feb 27 '14 at 07:38
  • Sure it's a bit complicated, but what is the alternative? Not using a typedef? You still need the type, but without a typedef you have to explicitly use the same function type everywhere it's needed, which is ten times more confusing, and of course error prone. Instead of having to get one typedef right, the programmer needs to get the type right in many places. – gnasher729 Feb 27 '14 at 12:58
  • 2
    "it is recommended" by whom? Typedefs for function pointers are very commonly used in numerous C APIs for callbacks and using a typedef means that the function that takes a function pointer as its parameter is much more readable. Unless you can use C++ lambdas, function pointer typedefs are IMO much better coding style than using them directly if you implement e.g. asynchronous API. – uliwitness Mar 03 '14 at 16:14
-7

typedef is defining a new type for use in your code, like a shorthand.

typedef typename _MyBase::value_type value_type;
value_type v;
//use v

typename here is letting the compiler know that value_type is a type and not an object inside of _MyBase.

the :: is the scope of the type. It is kind of like "is in" so value_type "is in" _MyBase. or can also be thought of as contains.

Possible duplicate : C++ - meaning of a statement combining typedef and typename

Community
  • 1
  • 1
Harsh
  • 2,852
  • 1
  • 13
  • 27
  • 10
    This answer is not helpful. The question clearly states that they understand the basic concept of a `typedef` (which you explained) but were puzzled by the more complex one (which you didn’t even touch on). – mirabilos Feb 27 '14 at 13:28