Apakah ada kerugian untuk melewati struct dengan nilai dalam C, daripada melewati pointer?
Jika struct besar, jelas ada aspek performansi menyalin banyak data, tetapi untuk struct lebih kecil, pada dasarnya harus sama dengan melewatkan beberapa nilai ke suatu fungsi.
Itu mungkin bahkan lebih menarik ketika digunakan sebagai nilai pengembalian. C hanya memiliki nilai pengembalian tunggal dari fungsi, tetapi Anda sering membutuhkan beberapa. Jadi solusi sederhana adalah dengan meletakkannya di struct dan mengembalikannya.
Apakah ada alasan untuk atau menentang ini?
Karena mungkin tidak jelas bagi semua orang apa yang saya bicarakan di sini, saya akan memberikan contoh sederhana.
Jika Anda memprogram dalam C, cepat atau lambat Anda akan mulai menulis fungsi yang terlihat seperti ini:
void examine_data(const char *ptr, size_t len)
{
...
}
char *p = ...;
size_t l = ...;
examine_data(p, l);
Ini bukan masalah. Satu-satunya masalah adalah bahwa Anda harus setuju dengan rekan kerja Anda di mana urutan parameter harus jadi Anda menggunakan konvensi yang sama di semua fungsi.
Tetapi apa yang terjadi ketika Anda ingin mengembalikan informasi yang sama? Anda biasanya mendapatkan sesuatu seperti ini:
char *get_data(size_t *len);
{
...
*len = ...datalen...;
return ...data...;
}
size_t len;
char *p = get_data(&len);
Ini berfungsi dengan baik, tetapi jauh lebih bermasalah. Nilai kembali adalah nilai balik, kecuali bahwa dalam implementasi ini tidak. Tidak ada cara untuk mengatakan dari atas bahwa fungsi get_data tidak diizinkan untuk melihat apa yang ditunjukkan oleh len. Dan tidak ada yang membuat kompiler memeriksa apakah suatu nilai benar-benar dikembalikan melalui pointer itu. Jadi bulan depan, ketika orang lain memodifikasi kode tanpa memahaminya dengan benar (karena dia tidak membaca dokumentasi?) Itu rusak tanpa ada yang memperhatikan, atau mulai crash secara acak.
Jadi, solusi yang saya usulkan adalah struct sederhana
struct blob { char *ptr; size_t len; }
Contoh-contoh dapat ditulis ulang seperti ini:
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();
Untuk beberapa alasan, saya pikir sebagian besar orang secara instingtif akan membuat exam_data mengambil pointer ke blob struct, tapi saya tidak mengerti mengapa. Itu masih mendapat pointer dan integer, itu hanya jauh lebih jelas bahwa mereka pergi bersama. Dan dalam kasus get_data tidak mungkin untuk mengacaukan dengan cara yang saya jelaskan sebelumnya, karena tidak ada nilai input untuk panjangnya, dan harus ada panjang yang dikembalikan.
gettimeofday
) menggunakan pointer, dan orang-orang mengambilnya sebagai contoh.
void examine data(const struct blob)
itu tidak benar.