简体   繁体   中英

C Function returning an Array

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 that char x()[] is also a valid construct. char x()[]也是有效的构造。 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?

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]; 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?

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.

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM