Все ли компиляторы C позволяют функциям возвращать структуры? - PullRequest
2 голосов
/ 10 марта 2010

Я работаю над программой на C и использую компилятор SDCC для устройства с архитектурой 8051. Я пытаюсь написать функцию GetName, которая будет читать 8 символов из флэш-памяти и возвращать массив символов в некоторой форме. Я знаю, что невозможно вернуть массив в C, поэтому я пытаюсь сделать это, используя такую ​​структуру:

//********************FLASH.h file*******************************
MyStruct GetName(int i);  //Function prototype

#define NAME_SIZE  8

typedef struct
{
    char Name[NAME_SIZE];
} MyStruct;

extern MyStruct GetName(int i);


// *****************FLASH.c file***********************************
#include "FLASH.h"

MyStruct GetName( int i)
{
     MyStruct newNameStruct;

     //...
     // Fill the array by reading data from Flash 
     //...

     return newNameStruct;
}

У меня пока нет ссылок на эту функцию, но по какой-то причине я получаю ошибку компилятора, которая говорит: «Функция не может вернуть агрегат». Значит ли это, что мой компилятор не поддерживает функции, которые возвращают структуры? Или я что-то не так делаю?

Ответы [ 4 ]

13 голосов
/ 10 марта 2010

SDCC пока не поддерживает структуры присваивания и возврата (если их вики обновлены):

Еще не реализовано в sdcc:

  • Тип данных double.
  • Структуры и объединения не могут быть назначены, переданы в качестве параметров функции или возвращаемых значений.
  • зарегистрировать спецификатор класса хранения в параметрах функции.

Может быть, вы должны сделать

void GetName(MyStruct* ret_name, int i);

функция вместо.


Тем не менее, вы должны поместить прототип функции до main и после MyStruct. Если прототипов нет, предполагается, что функция вернет int.

MyStruct GetName(int i);
void main(void) { ...

(Кроме того, функция main должна быть int main(void) или int main(int argc, char** argv). Она не должна возвращать void.)

6 голосов
/ 10 марта 2010

Все пост-ANSI C89 / 90 компиляторы позволяют возвращать объекты struct. Классических (педантичных) компиляторов K & R C нет.

Однако в любом случае вы должны сначала объявить функцию. то есть до вы называете это. И char[8] Name внутри вашей структуры не является допустимым объявлением. Действительная форма: char Name[8].

Ваша функция, возвращающая указатель на массив, объявлена ​​правильно. Это ваш размер макрос, который сломан. Должно быть

#define NAME_SIZE 8 

Примечание: нет = символа.

1 голос
/ 10 марта 2010

Да, функции могут возвращать структуры в C. Ваш код выше имеет несколько ошибок. С некоторыми изменениями, он правильно компилируется в gcc (у ​​меня не установлен sdcc, чтобы попробовать, но, пожалуйста, попробуйте код ниже.

 struct MyStruct
 {
   char Name[8];
 }; 

 struct MyStruct GetName( int i)
 {
      struct MyStruct newNameStruct;

      //...
      // Fill the array by reading data from Flash 
      //...
     return newNameStruct;
 } 


 int main(void)
 {
     int NameIndex = 3;
     struct MyStruct testStruct;
     testStruct = GetName(NameIndex);
     return 0;  
 }
0 голосов
/ 10 марта 2010

Я действительно не хотел бы использовать компилятор C, который не реализовывал структурный вызов и возвращал по значению, как предлагает КенниМТ. На самом деле такой компилятор не следует называть компилятором Си. Если компилятор вообще реализует структуры, возврат по значению не сложно реализовать.

В любом случае, для работы с вашим компилятором вам понадобится что-то вроде:

typedef struct
{
    char Name[NAME_SIZE];
} MyStruct;

void f( MyStruct * m ) {
   strcpy( m->Name, "foo" );
}

int main() {
    MyStruct ms;
    f( & ms );
    return 0;
}
...