4

I was reading litb's question about SFINAE here and I was wondering exactly what his code is declaring. A simpler (without the templates) example is below:

int (&a())[2];

What exactly is that declaring? What is the role of the &? To add to my confusion, if I declare the following instead

int b()[2];

I get an error about declaring a function that returns an array, while the first line has no such error (therefore, one would think the first declaration is not a function). However, if I try to assign a

a = a;

I get an error saying I'm attempting to assign the function a... so now it is a function. What exactly is this thing?

Community
  • 1
  • 1
GRB
  • 1,515
  • 2
  • 11
  • 10
  • I used that rather weird construct to see what function was called. sizeof(a()) will give you sizeof(int[2]) . The other function would be declared as int(&a())[1]; and if that one was called, it would give sizeof(int[1]). It makes use of the fact that for any T, sizeof(T&) == sizeof(T) – Johannes Schaub - litb Jun 21 '09 at 18:38

3 Answers3

17

There's these awesome programs called cdecl and c++decl. They're very helpful for figuring out complicated declarations, especially for the byzantine forms that C and C++ use for function pointers.

tyler@kusari ~ $ c++decl
Type `help' or `?' for help
c++decl> explain int (&a())[2]
declare a as function returning reference to array 2 of int
c++decl> explain int b()[2]
declare b as function returning array 2 of int

a returns a reference, b does not.

Tyler McHenry
  • 74,820
  • 18
  • 121
  • 166
  • wow, those programs are useful. I don't suppose a Windows port exists? – jalf Jun 21 '09 at 17:23
  • I don't know of a canonical version of cdecl for Windows (although of course you could always use the Linux version through Cygwin), but if you google for "cdecl.zip" it seems to pull up a few windows ports that various people have done. – Tyler McHenry Jun 21 '09 at 17:30
  • 2
    That is actually very useful. – Martin York Jun 21 '09 at 18:04
  • As far as I can see, the .zip dates back to 1987, which means it's probably not very useful for C++ syntax... :) But thanks, I'll check it out. Or just use it through Cygwin – jalf Jun 21 '09 at 19:45
  • ran into those programs a while ago. legendary! – Matt Joiner Jun 24 '10 at 11:51
  • @jalf: c++ on winders? cast away your shackles! – Matt Joiner Jun 24 '10 at 11:53
  • @Matt: I love when people claim that the way to "cast away your shackles" is to limit your options. Because yes, I'm so much more free and unshackled if I target Linux than I am if I target both Linux and Windows. ;) – jalf Jun 24 '10 at 13:37
  • C++ does not allow functions returning arrays, though. – fredoverflow Mar 12 '13 at 09:03
8

For future reference, you may find this link helpful when you have a particularly difficult C/C++ declaration to decipher:

How To Read C Declarations

For completeness, I will repeat what others have said to directly answer your question.

int (&a())[2];

...declares a to be a zero-argument function which returns a reference to an integer array of size 2. (Read the basic rules on the link above to have a clear understanding of how I came up with that.)

int b()[2];

...declares b to be a zero-argument function which returns an integer array of size two.

Hope this helps.

Andrew Song
  • 3,120
  • 1
  • 27
  • 22
2
int (&a())[2];

It declares a symbol a that is a function that takes no arguments and returns a reference to a two-element array of integers.

 int b()[2];

This declares a symbol b that is a function that takes no arguments and returns a two-element array of integers... this is impossible by the design of the language.

It is relatively simple: get an operator precedence chart, start the symbol name (a) and start applying the operators as you see from their precedence. Write down after each operation applied.

Juliano
  • 39,173
  • 13
  • 67
  • 73