Gọi các thủ tục lập trình theo cấu trúc phù hợp…

lập trình


Tôi có một câu hỏi có thể khiến bạn khó chịu, nhưng đồng thời nó cũng có thể khiến tôi bối rối, nhưng thế này nhé.

Trước tiên hãy có một số ví dụ lập trình để làm việc:

Tuyên bố về một thói quen “C”
int RetIntDayNum(char * datetrg, int * intdaynum, int * iostat);

Khai báo thủ tục “C” đơn giản thực tế.
int RetIntDayNum(char * datetrg, int * intdaynum, int * iostat) {
////



trở lại (1);
}

Khai báo lệnh gọi “C”: Quy trình 1.
iretv = RetIntDayNum(cdatestring, &idaynum, &iostat);

Khai báo lệnh gọi “C”: Quy trình 2.
iretv = RetIntDayNum(cdatestring, &idaynum);

Được rồi, đây là câu hỏi…
Khi gọi quy trình “C”, bạn nên sử dụng “Quy trình 1”. Nhưng khi thực hiện dự án lập trình của mình, sau này tôi đã phát hiện ra và
nhận ra rằng tôi đang sử dụng phương pháp “Quy trình 2” và mỗi lần tôi biên soạn chương trình này;
Nó biên dịch OK và chạy OK.

Hiện tại, tôi đang sử dụng môi trường Enterprise MSVC 2019, trên Nền tảng Windows 10.

Tôi biết sử dụng “Quy trình 1” là cách làm đúng nhưng tại sao việc sử dụng “Quy trình 2” lại không làm cho chương trình
nổ tung?. Tại sao. Hay đó là một vụ nổ chờ đợi sẵn sàng xảy ra?
Hiện tại, tôi phải quay lại chương trình lớn này và sửa tất cả các lỗi trong chương trình của mình. Nhưng điều đó làm phiền
cho tôi biết tại sao cách tiếp cận “Quy trình 2” không khiến chương trình bị hỏng (hoặc bị hủy bỏ) ngay bây giờ.

Hay liệu vụ nổ chờ đợi này sẽ xảy ra, một khi điều này
chương trình chạy trên nền tảng windows hoàn toàn khác??

Tâm trí tò mò của tôi muốn biết…
Và một lần nữa, cảm ơn!

Những gì tôi đã thử:

những gì được hiển thị trong vùng câu hỏi và trong dự án lập trình của tôi.

Giải pháp 1

Nó phụ thuộc vào trình biên dịch: hầu hết sẽ báo lỗi “quá ít đối số để hoạt động” khi bạn cố gọi nó bằng hai tham số.

Ngoài ra, nó có thể sẽ nổ tung khi bạn cố gắng sử dụng iostat trong hàm vì giá trị của nó sẽ không được xác định và bạn có thể đang đọc hoặc ghi vào bất kỳ phần nào của bộ nhớ.

Tôi sẽ kiểm tra những gì bạn đang sử dụng – MSVC là MicroSoft Visual C và đó là một sản phẩm độc lập đã trở thành một phần của Visual Studio khoảng 20 năm trước và chưa bao giờ có phiên bản 2019.
Và tôi khá chắc chắn rằng VS 2019 sẽ gây ra lỗi với quá ít tham số cho chương trình C (có thể xác định các hàm trong C có số lượng đối số thay đổi – được gọi là hàm variadic – nhưng phải có một cú pháp đặc biệt và cách bạn sử dụng chúng là khác nhau).

Giải pháp 2

Trước hết, cần phải phân biệt giữa khai báo trong quá trình triển khai và lệnh gọi hàm. Dòng sau đây không phải là một lời khai báo mà là một bài tập:

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

VS2019 thường luôn phát sinh lỗi nếu không tìm được cách triển khai phù hợp cho lệnh gọi.

Cuộc gọi của

C
iretv = RetIntDayNum(cdatestring, &idaynum);

gây ra lỗi C2198: “RetIntDayNum”: Không đủ đối số cho cuộc gọi.
hoặc lỗi C2660: “RetIntDayNum”: Hàm không chấp nhận 2 đối số

Vì VS2019 là trình biên dịch C++ nên có thể nảy sinh một số câu hỏi.
Mã được biên dịch dưới dạng mã C hay C++ và với phiên bản trình biên dịch nào? VS2019 về cơ bản có thể biên dịch theo các tiêu chuẩn sau: C++14, C++17, C++20, Legacy MSVC, std:c11, std:c17.

Lời giải thích duy nhất tôi có thể nghĩ ra cho hành vi được mô tả là ở đâu đó có một hàm khác có cùng tên và chỉ có 2 tham số.
Không thể trả lời câu hỏi liệu chương trình có thể “nổ” sau khi biên dịch (không có lỗi) do thiếu tham số hay không, vì người ta không biết các chức năng thực sự làm gì.
Trong mọi trường hợp, bạn chỉ có thể truy cập các biến mà trình biên dịch cũng hiển thị. Nếu có các biến toàn cục có cùng tên, điều này có thể gây khó chịu.

Giải pháp 3

Tôi không thể tin được điều đó. Vì vậy, tôi đã thử đoạn mã sau

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");
  return 0;
}

trên hai nền tảng khác nhau:

  • Hộp Linux, gcc 9.4
  • Windows 10, VS2022, CL 19.34

Cả hai trình biên dịch đều đưa ra một lỗi:

  • lỗi: quá ít đối số để hoạt động ‘RetIntDayNum’ (gcc)
  • lỗi C2198: ‘RetIntDayNum’: quá ít đối số cho cuộc gọi (CL)

コメント

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