Memanggil rutinitas pemrograman dalam struktur yang tepat…

pemrograman


Saya punya pertanyaan yang mungkin membebani Anda, tetapi mungkin juga membuat saya malu pada saat yang sama, tapi begini saja.

Mari kita lihat beberapa contoh pemrograman yang akan digunakan terlebih dahulu:

C
   Declaration of a "C" routine
        int RetIntDayNum(char * datestrg, int * intdaynum, int * iostat);

   Declaring the actual simple "C" routine.
        int RetIntDayNum(char * datestrg, int * intdaynum, int * iostat) {
////
            ... 
            ... 
            ... 
            return(1);
        } 

   Declaring a "C" call:   Routine 1. 
          iretv = RetIntDayNum(cdatestring, &idaynum, &iostat);

   Declaring a "C" call:   Routine 2. 
          iretv = RetIntDayNum(cdatestring, &idaynum);

Oke, inilah pertanyaannya…
Dalam memanggil rutin “C”, Anda harus menggunakan “Rutin 1”. Namun saat menyusun proyek pemrograman saya, saya kemudian mengetahui dan
menyadari bahwa saya telah menggunakan pendekatan “Rutin 2”, dan setiap kali saya mengkompilasi program ini;
Itu dikompilasi dengan OK dan berjalan dengan baik.

Saat ini, saya menggunakan lingkungan Enterprise MSVC 2019, pada Platform Windows 10.

Saya tahu menggunakan “Rutin 1” adalah cara yang benar dalam melakukan sesuatu, tetapi mengapa penggunaan “Rutin 2” tidak membuat program
meledakkan?. Mengapa. Atau apakah itu ledakan yang menunggu dan siap terjadi?
Saat ini, saya harus kembali ke program besar ini dan memperbaiki semua kesalahan program saya. Tapi itu mengganggu
saya mengapa pendekatan “Rutin 2” tidak menyebabkan program meledak (atau hilang) sekarang.

Atau akankah ledakan yang menunggu ini terjadi, pada saat ini
program berjalan pada platform windows yang sama sekali berbeda??

Pikiranku yang penasaran ingin tahu…
Dan sekali lagi, Terima kasih!

Apa yang saya coba:

apa yang ditampilkan di area pertanyaan, dan dalam proyek pemrograman saya.

Solusi 1

Itu tergantung pada kompilernya: sebagian besar akan memberi Anda kesalahan “terlalu sedikit argumen untuk berfungsi” ketika Anda mencoba memanggilnya dengan dua parameter.

Selain itu, mungkin akan meledak ketika Anda mencoba menggunakan iostat dalam fungsi karena nilainya tidak terdefinisi dan Anda dapat membaca atau menulis ke bagian memori mana pun.

Saya akan memeriksa apa yang Anda gunakan – MSVC adalah MicroSoft Visual C dan itu adalah produk mandiri yang menjadi bagian dari Visual Studio sekitar 20 tahun yang lalu dan tidak pernah memiliki versi 2019.
Dan saya cukup yakin VS 2019 akan menimbulkan kesalahan pada terlalu sedikit parameter untuk program C (dimungkinkan untuk mendefinisikan fungsi dalam C yang memiliki sejumlah argumen – disebut fungsi variadik – tetapi itu memerlukan sintaksis khusus dan cara Anda menggunakannya berbeda).

Solusi 2

Pertama-tama, perbedaan harus dibuat antara deklarasi dalam implementasi dan pemanggilan suatu fungsi. Baris berikut ini bukan deklarasi melainkan tugas:

C
iretv = RetIntDayNum(cdatestring, &idaynum, &iostat);

VS2019 biasanya selalu menghasilkan kesalahan jika tidak dapat menemukan implementasi yang cocok untuk panggilan tersebut.

Panggilan dari

C
iretv = RetIntDayNum(cdatestring, &idaynum);

menyebabkan kesalahan C2198: “RetIntDayNum”: Argumen tidak cukup untuk panggilan.
atau kesalahan C2660: “RetIntDayNum”: Fungsi tidak menerima 2 argumen

Karena VS2019 adalah kompiler C++, beberapa pertanyaan mungkin muncul.
Apakah kode dikompilasi sebagai kode C atau C++ dan dengan versi kompiler yang mana? VS2019 pada dasarnya dapat dikompilasi dengan standar berikut: C++14, C++17, C++20, Legacy MSVC, std:c11, std:c17.

Satu-satunya penjelasan yang dapat saya pikirkan untuk perilaku yang dijelaskan adalah bahwa di suatu tempat terdapat fungsi lain dengan nama yang sama dan hanya 2 parameter.
Pertanyaan apakah program dapat “meledak” setelah kompilasi (bebas kesalahan) karena parameter yang hilang tidak dapat dijawab, karena tidak diketahui fungsi sebenarnya yang dilakukan.
Bagaimanapun, Anda hanya dapat mengakses variabel yang juga terlihat oleh kompiler. Jika ada variabel global dengan nama yang sama, hal ini mungkin tidak menyenangkan.

Solusi 3

Saya tidak percaya itu. Jadi saya mencoba potongan kode berikut

C
#include <stdio.h>
  

int RetIntDayNum(char * datestrg, int * intdaynum, int * iostat);

int main()
{

  char foo[] = "foo";
  int daynum = 42;
  int iostat = 10;

  RetIntDayNum(foo, &daynum, &iostat);
  RetIntDayNum(foo, &daynum);

  return 0;
}


int RetIntDayNum(char * datestrg, int * intdaynum, int * iostat)
{
  printf("datestrg %s, intdaynum %d, iostat  %d\n", datestrg, *intdaynum, *iostat);
  return 0;
}

pada dua platform berbeda:

  • Kotak Linux, gcc 9.4
  • Windows 10, VS2022, CL 19.34

Kedua kompiler memberikan kesalahan:

  • kesalahan: terlalu sedikit argumen untuk berfungsi ‘RetIntDayNum’ (gcc)
  • kesalahan C2198: ‘RetIntDayNum’: terlalu sedikit argumen untuk panggilan (CL)

コメント

タイトルとURLをコピーしました