-1

I always thought that when you want to return an array from a function, the only way to do that was using pointers like so: char * func();

But yesterday, while I was going through K & R, I noticed wrongly assumed that char x()[] is also a valid construct. So I went ahead to test this out and wrote up the following code:

#include <stdio.h>
#include <stdlib.h>

char string1[10] = "123456789";


char x(void)[10];

int main(void) {
    printf("string returned by x() is %s",x());
    return EXIT_SUCCESS;
}

char x(void)[10] {
    return x;
}

Compiling using GCC on Windows, this threw the following errors:

..\src\07arrreturn.c:7:6: error: 'x' declared as function returning an array
..\src\07arrreturn.c: In function 'main':
..\src\07arrreturn.c:10:2: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int' [-Wformat]
..\src\07arrreturn.c: At top level:
..\src\07arrreturn.c:14:6: error: 'x' declared as function returning an array
..\src\07arrreturn.c: In function 'x':
..\src\07arrreturn.c:15:2: warning: return makes integer from pointer without a cast [enabled by default]

What is happening? am I mis-understanding what the book says? How can you return more than one value (or address) from a function? Isn't that restricted by the fact that you only have a single limited size CPU register that can hold the return value? If you have to return a big chunk of data, you can do so only by returning the address to it right?

Whats the deal with char x()[]? Is such a thing even used?

EDIT: I DID in fact misread the stuff from K&R. See comment below.

lithiumhead
  • 861
  • 1
  • 9
  • 19
  • 4
    Which page in which edition of K&R? – Jonathan Leffler May 24 '13 at 06:10
  • 1
    @JonathanLeffler I too had apprehensions,but decided to stay silent and watch when the OP said he sourced it from K&R!! – Rüppell's Vulture May 24 '13 at 06:15
  • Oh damn! I think the analysis paralysis bug hit me bad - sorry for the confusion! K & R DOES NOT actually say anything about functions returning arrays. I misread a few lines on page 122 (Section 5.12 Complicated Declarations of 2nd Edition of K & R Prentice Hall Edition). There were a an example there where pointers to functions return pointers to array, I missed out reading the second "pointer" And I remember punching in char x()[] on cdecl.org and checking if it made sense [see this](http://cdecl.ridiculousfish.com/?q=char+x%28%29%5B%5D) Sorry! – lithiumhead May 24 '13 at 09:39

3 Answers3

6

char x()[] is also a valid construct

Not as-is, and not quite in this context.

You can use similar syntax to:

  • declare a pointer to array: char (*arrPtr)[20];

  • declare an array of function pointers: void (*foo[20])(void);

  • dereference the return value (pointer) of a function call: char *foo(); char c = foo()[0];

  • declare a function that returns a pointer to array: char (*foo())[20]

  • or the same thing with a function pointer: char (*(*foo)())[20]

Which one of these are you looking for?

5

The C standard (ISO/IEC 9899:2011) says unequivocally:

6.7.6.3 Function declarators (including prototypes)

Constraints
1 A function declarator shall not specify a return type that is a function type or an array type.

Thus your code is invalid.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • but valid in C++! [here](http://stackoverflow.com/questions/5157439/why-doesnt-c-support-functions-returning-arrays) I could find why its so – Grijesh Chauhan May 24 '13 at 06:25
  • 1
    Not valid in C++ either. ISO/IEC 14882:2011 §8.3.5 **Functions**: ¶8 _[...] Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things._ – Jonathan Leffler May 24 '13 at 06:49
3

K&R C is quite old. In ANSI C (C89), functions returning arrays aren't allowed and what you see is the result of this. First, you get errors for the declaration of x() as a function returning an array and due to this error, x() is never correctly declared and thereby treated like a function returning an int (because this used to be the default return type). This returned int is then supposed to be interpreted as char * generating the final warning.

If you need to return an array, you can wrap it in a struct. Otherwise return a pointer (make sure that the memory it points to is valid after returning).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char string1[10] = "123456789";

struct ret_s {
    char string1[10];
};

struct ret_s x(void);

int main(void) {
    struct ret_s r = x();
    printf("string returned by x() is %s\n", r.string1);
    return EXIT_SUCCESS;
}

struct ret_s x(void) {
    struct ret_s r;
    strcpy(r.string1, string1);
    return r;
}
Florian Rhiem
  • 1,758
  • 1
  • 14
  • 23
  • Yes! this is how I normally do things, was just curious that there might be this other way of doing things - which I now know to be invalid! – lithiumhead May 24 '13 at 09:46