Bagaimana membuatnya jelas bahwa suatu fungsi sedang diakses dari luar?

9

Ini adalah pertanyaan khusus C. Saya mencoba untuk menjaga segala kemungkinan di dalam batas unit terjemahan, memaparkan hanya beberapa fungsi melalui .hfile. Yaitu, saya memberikan statictautan ke objek tingkat file.

Sekarang, beberapa fungsi perlu dipanggil oleh modul lain, tetapi tidak secara langsung. Modul / file / unit terjemahan saya berlangganan ke modul lain, meneruskan sebuah pointer ke suatu fungsi. Kemudian, pada peristiwa tertentu, penunjuk dipanggil dengan beberapa argumen.

Jadi saya bertanya-tanya bagaimana membuatnya sangat jelas bahwa fungsi-fungsi itu dipanggil dari beberapa lokasi yang tidak jelas.

  • Haruskah mereka staticatau extern(dan mengekspos mereka di .h)?
  • Haruskah saya memasukkan beberapa petunjuk dalam nama fungsi?
  • Atau cukupkah memberi komentar "dipanggil oleh X"?
Vorac
sumber
1
Itu pertanyaan yang sangat bagus. Solusi saya (dengan yang saya sama sekali tidak terlalu senang, itu sebabnya saya hanya memasukkannya dalam komentar) adalah membuat beberapa file header, namanya masuk akal, dan mengelompokkan fungsi pada ruang lingkup yang saya inginkan. Untuk perpustakaan AStar yang saya buat saya punya AStar.h, AStar_private.h, AStar_packagePrivate.h, dll ...
Shivan Dragon

Jawaban:

2

Dari perspektif unit kompilasi (file), satu-satunya hal yang harus Anda perhatikan adalah apakah fungsi tersebut tersedia di luar atau tidak. Menyediakannya berarti panggilan itu dimaksudkan, dan Anda harus beroperasi dengan asumsi bahwa panggilan itu akan terjadi. Kekhawatiran Anda dengan fungsi itu sendiri dimulai pada titik masuknya. Bagaimana kontrol sampai di sana pada mulanya hanya penting bagi kode yang membuatnya terjadi.

Karena tautan dalam setiap implementasi CI yang diketahui adalah simbolis, apa pun yang memanggil fungsi harus merujuk ke simbolnya:

foo();  /* Direct */

some_function_pointer_t funcs[] = { &foo, &bar, &baz };  /* Indirect */

Jika Anda secara keliru menyatakan foo()sebagai static, program Anda tidak akan ditautkan. Jika Anda mendeklarasikannya non- static, Anda memiliki fungsi terbuka yang tidak dipanggil. Pertanyaan tentang apakah suatu fungsi digunakan atau tidak dapat diselesaikan dengan membuang tabel simbol file objek Anda atau mencarinya di sumber.

Blrfl
sumber
1

Jadi saya mengembara bagaimana membuatnya sangat jelas bahwa fungsi-fungsi itu dipanggil dari beberapa lokasi yang tidak jelas.

Tentukan "tidak jelas".
Metode harus diekspos melalui "antarmuka" yang didefinisikan dengan baik dan, seperti yang telah disarankan Shivan Dragon, "antarmuka" itu adalah file .h Anda. Jika Anda tidak memberikan program lain file header "kanan" maka program tidak dapat memanggil metode tersebut.

Haruskah mereka statis atau eksternal (dan mengeksposnya dalam.

static mungkin baik-baik saja selama Anda tidak memiliki kelas [-seperti konstruksi] yang berisi data instance.
externberarti Anda tidak benar-benar mengimplementasikannya sama sekali; suatu implementasi "diperoleh" dari tempat lain selama proses penautan.

Haruskah saya memasukkan beberapa petunjuk dalam nama fungsi?

Atau cukupkah memberi komentar "dipanggil oleh X"?

Benar-benar tidak.

Komentar seperti ini, betapapun baiknya maksudnya, sudah usang saat Anda selesai menulisnya.

Phill W.
sumber
Mengatasi poin pertama Anda, fungsinya disebut sebagai berikut. Komponen saya termasuk .hfile eksternal . Ini memanggil fungsi dari sana dan memberikannya penunjuk ke salah satu fungsi modul itu sendiri. Kemudian kode eksternal memanggil apa pun yang ada di pointer itu. Jadi fungsi saya dipanggil oleh seseorang, yang tidak menyertakan file header saya, melainkan saya sertakan.
Vorac
1
Mengenai poin kedua, sejauh pemahaman saya, objek, didefinisikan pada ruang lingkup file memiliki hubungan eksternal secara default; oleh karena itu externkata kunci tersebut berlebihan` .
Vorac
0

Jika fungsi panggilan balik didefinisikan dalam modul Anda dan pengguna tidak akan pernah memberikan salah satu dari miliknya sendiri, saya pikir Anda dapat menggunakan placeholder selama fase inisialisasi. Placeholder biasanya merupakan enumyang kemudian diterjemahkan secara internal ke staticfungsi yang tepat .

lorcap
sumber
0

Saya masih akan membuatnya static(mereka tidak dimaksudkan untuk dihubungkan dan dipanggil oleh sembarang orang), dan menandai tujuan mereka sebagai callback yang disediakan untuk fungsi eksternal atas nama mereka.

static karena saya berusaha menyembunyikan apa yang bisa saya sembunyikan, sebanyak yang saya bisa sembunyikan.

Tandai mereka atas nama mereka, karena a), komentar keluar dari tanggal, dan b), menjadi jelas di tempat di mana panggilan balik diberikan bahwa fungsi ini dimaksudkan untuk digunakan seperti itu: ini pada dasarnya membuatnya menjadi bendera merah untuk mengambil alamat fungsi yang tidak mengikuti konvensi penamaan.

Sebastian Redl
sumber
0

Pengubah lingkup harus digunakan terutama sebagai informasi untuk kompiler, bukan sebagai bentuk dokumentasi "cukup dekat". Penggunaan statickhususnya memungkinkan kompiler C untuk membuat fungsi tidak dapat digunakan dari luar modul, termasuk sebagai callback - bukan apa yang Anda inginkan, meskipun mungkin berfungsi dengan kompiler Anda saat ini.

Tentu saja Anda harus menambahkan komentar pada kode tersebut, karena Anda dapat melihatnya sebagai situasi yang berpotensi membingungkan. Apa pun yang tidak biasa atau tidak terduga memerlukan komentar yang sesuai. Tetapi, seperti yang dinyatakan dalam jawaban lain, komentar bisa tidak dibaca atau menjadi ketinggalan zaman.

Jadi, satu-satunya pilihan yang tersisa adalah nama fungsi untuk menunjukkan itu adalah panggilan balik. Sebagian besar contoh yang saya lihat menggunakan _callbackatau _cbsebagai akhiran, atau cb_sebagai awalan. Gunakan formulir panjang jika panggilan balik tidak biasa dalam kode Anda, formulir singkat jika itu umum.

Jonathan Giddy
sumber