すべての C コンパイラは関数が構造体を返すことを許可しますか?
質問
私は C でプログラムを作成しており、8051 アーキテクチャ デバイス用の SDCC コンパイラを使用しています。フラッシュメモリから8文字を読み取り、何らかの形式で文字配列を返すGetNameという関数を作成しようとしています。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;
}
私はまだこの関数への参照はありませんが、何らかの理由で、「関数は集計を返すことはできません」というコンパイラエラーが表示されます。これは、コンパイラが構造体を返す機能をサポートしていないことを意味しますか?それとも私が何か間違ったことをしているだけなのでしょうか?
解決
SDCC はまだ構造体の割り当てと戻り値をサポートしていません (Wiki が最新の場合):
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
.)
他のヒント
すべてのポストANSI C89 / 90コンパイラのstructオブジェクトを返すことができます。クラシック(衒学)K&R Cコンパイラではありません。
しかし、どのような場合には、最初に関数を宣言しなければなりません。すなわち、のの前に、あなたはそれを呼び出します。そして、あなたの構造体の内部char[8] Name
は有効な宣言ではありません。有効な形式はchar Name[8]
です。
あなたへのポインタの配列を返す関数を正しく宣言されています。それは壊れてあなたのサイズのマクロです。でなければなりません。
#define NAME_SIZE 8
注:なし=
文字
はい、機能はあなたのコードは、上記のいくつかのエラーを持っている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;
}
私は本当にKennyMTはあなたにはない示唆するように、構造の呼び出しを実装し、値によって返されませんでしたCコンパイラを使用したいとは思わないでしょう。実際には、コンパイラは本当にCコンパイラと呼ばれるべきではありません。コンパイラは、すべての構造を実装している場合、値による返品は実装するのは難しいことではありません。
とにかく、あなたのコンパイラで動作するようにあなたのような何かをしたいでしょう
typedef struct
{
char Name[NAME_SIZE];
} MyStruct;
void f( MyStruct * m ) {
strcpy( m->Name, "foo" );
}
int main() {
MyStruct ms;
f( & ms );
return 0;
}