一般的なアドバイスと同様に、最も読みやすい方法でコーディングしてください。プロファイリングでボトルネックであることが示された場合にのみ、その方法から変更してください。
コピーが必要になる可能性のある大きな構造体を返すつもりでない限り、違いはごくわずかです。大きな構造体の場合でも、コンパイラが巧妙であれば、生成されたコードを見ると、2 つが本質的に同等であることがわかります。
ほとんどのコンパイラはレジスタを使用してレジスタに収まる値を返しますが、これは非常に高速です。したがって、そのような値の場合、ポインターを使用して値を返すことが利点であるとは想像できません。
最後に、エラー コードを関数値として返すのは一般的な C 規則です。したがって、この場合、メモリへのポインターを使用して値を返すことも一般的です。この規則を使用する API は統一されている傾向があり、その結果、使いやすくなっています。
非常に簡単な例:
struct list_s {
int size;
struct element_s *array;
}
int initialize_list(struct list_s *list, int size)
{
int err_code = 0;
// do the intialization of *list, setting err_code if something goes wrong
list->array = malloc(size * sizeof(struct element_s));
if (list->array)
list->size = size;
else {
size = 0;
err_code = ERR_OUT_OF_MEMORY;
}
return err_code;
}