構造内で VLA を宣言できるようにする、優れた GCC 拡張機能を使用しています。今のところ、この方法で VLA を関数に (値で) 渡す方法を見つけました。また、非常に限られたコンテキストで返す方法を見つけました。
この例の関数コードは次のとおりです。
extern void func3()
{
size_t size;
scanf("%zu", &size);
struct tx{int _[size];} fn()
{
struct tx rt;
for(size_t i=0; i < size; ++i)
scanf("%d", &rt._[i]);
return rt;
}
volatile __typeof__(fn) *pf = fn;
}
上記の例は、テスト目的で設計されています (特に、コンパイルされたバイナリ コードを比較するため)。
ただし、返される配列のサイズは関数の異なる呼び出し間で変化しないため、これはかなり制限されています。
返された配列のサイズを、関数パラメーターの 1 つまたはこの関数の他のローカルと等しくするにはどうすればよいでしょうか。
alloca
割り当てられたメモリは関数終了 (IRC) ですぐに破棄されるため、この場合は役に立たないと思います。
私はこのようなものを書きたい:
/*???*/ func5()
{
size_t size;
scanf("%zu", &size);
struct {int _[size];} rt;
for(size_t i=0; i < size; ++i)
scanf("%d", &rt._[i]);
return rt; //ok - return the structure
}
言い換えれば、疑問符内の型は何でしょうか? または、他の解決策があるかもしれません(ただし、を使用せずにmalloc
)?
このような関数の理論的な使用法では、返された構造体のサイズを呼び出し元が利用できないため、返された値を格納するために理論的には別の型が必要になります (これを回避する方法がない限り?)。しかし、一見すると、次のようになります。
size_t size;
//scanf("%zu", &size);
struct {int _[size];} tmp; //create locally VM type
//compatible with the one
//returned by our theoretical func5
//we can't directly initialize tmp here (gcc complains)
tmp = ((__typeof__(tmp) (*)())func5)(); //direct assignment between VM structures
//works here on the other hand
//as function return value is rvalue and we can't
//take its pointer and cast it to our local VM structure type
//we instead cast the function pointer
このようなことをすると:
__typeof__(func5()) tmp = func5();
func5
VM の戻り値の型は、その引数またはローカル変数に依存するため、機能しません。ただし、この関数はまだ定義できないため、現時点ではすべて理論上のものです。