ポインタを渡すのではなく、Cで構造体を値で渡すことの欠点はありますか?
構造体が大きい場合、明らかに大量のデータをコピーするパフォーマンスの側面がありますが、構造体が小さい場合、基本的には、いくつかの値を関数に渡すことと同じです。
戻り値として使用すると、さらに興味深いかもしれません。Cには関数からの戻り値が1つしかありませんが、多くの場合、いくつか必要です。簡単な解決策は、それらを構造体に入れて返すことです。
これには賛成または反対の理由がありますか?
ここで私が話していることは誰にとっても明白ではないかもしれないので、簡単な例を挙げます。
Cでプログラミングしている場合は、遅かれ早かれ次のような関数の記述を開始します。
void examine_data(const char *ptr, size_t len)
{
...
}
char *p = ...;
size_t l = ...;
examine_data(p, l);
これは問題ではありません。唯一の問題は、すべての関数で同じ規則を使用するために、パラメーターの順序を同僚に同意する必要があることです。
しかし、同じ種類の情報を返したい場合はどうなりますか?通常は次のようになります。
char *get_data(size_t *len);
{
...
*len = ...datalen...;
return ...data...;
}
size_t len;
char *p = get_data(&len);
これは正常に機能しますが、はるかに問題があります。戻り値は戻り値ですが、この実装ではそうではありません。上記から、関数get_dataがlenが指すものを見ることが許可されていないことを知る方法はありません。そして、値がそのポインタを通じて実際に返されることをコンパイラにチェックさせるものは何もありません。だから来月、誰かがコードを正しく理解せずにコードを変更すると(彼はドキュメントを読んでいないため)、だれにも気付かれずにコードが壊れるか、ランダムにクラッシュし始めます。
だから、私が提案する解決策は単純な構造です
struct blob { char *ptr; size_t len; }
例は次のように書き直すことができます。
void examine_data(const struct blob data)
{
... use data.tr and data.len ...
}
struct blob = { .ptr = ..., .len = ... };
examine_data(blob);
struct blob get_data(void);
{
...
return (struct blob){ .ptr = ...data..., .len = ...len... };
}
struct blob data = get_data();
どういうわけか、ほとんどの人は本能的にexamine_dataにstruct blobへのポインターを取得させると思いますが、その理由はわかりません。それはまだポインタと整数を取得します、それらが一緒に行くことはちょうどより明確です。そして、get_dataの場合、長さの入力値がなく、返された長さがなければならないため、前に説明した方法で失敗することはありません。
gettimeofday
代わりにポインターを使用します。
void examine data(const struct blob)
は、間違っています。