Ai nhận được giá trị được trả về bởi hàm main ()?


34

Tôi biết rằng trong các máy tính, giá trị được trả về bởi main()hàm được hệ điều hành nhận. Nhưng, điều gì xảy ra trong main()chức năng của vi điều khiển?


7
Tôi luôn sử dụng void main () khi tôi đang sử dụng C cho vi điều khiển PIC. Khi sử dụng trình biên dịch C cho vi điều khiển, nó thực sự không thành vấn đề. Bởi vì không có hệ điều hành nào chạy (nói) "main.c". Nếu có một cái gì đó giống như RTOS chạy trong vi điều khiển đó, thì hệ điều hành là "main.c".
abdullah kahraman

4
Không thực sự là một bản sao, nhưng ít nhất có liên quan: Electronics.stackexchange.com/q/30830/4950
PetPaulsen

1
Làm thế nào chức năng khởi động được xác định thường không phải là do bạn quyết định. Môi trường bạn đang sử dụng sẽ ghi lại các biểu mẫu chức năng khởi động được hỗ trợ. Việc triển khai C được lưu trữ được yêu cầu để hỗ trợ hai hình thức maincó hai chữ ký khác nhau, cả hai đều trả lại int. Nếu bạn đang sử dụng triển khai C tự do, thì việc triển khai đó chỉ ra cách bạn nên viết chức năng khởi động. Bạn không thể viết voidhàm trả về chỉ vì nó không trả về. Các hành vi không quay trở lại là khác với chức năng loại mà ảnh hưởng đến công ước chung gọi.
Kaz

Câu trả lời:


42

Trên một vi điều khiển, main()không thực sự được mong đợi sẽ thoát ra và hành vi nếu nó không được xác định - do đó, bất cứ ai đã viết thời gian chạy C cho vi điều khiển. Tôi đã thấy các hệ thống:

  • Có một vòng lặp ngầm xung quanh main(), do đó nếu nó thoát, nó chỉ đơn giản được gọi một lần nữa.
  • Có một vòng lặp "tự nhảy" đơn giản được thực thi nếu main()thoát ra.
  • Đơn giản chỉ cần thực thi phần còn lại của bộ nhớ mã theo lệnh gọi đến main(). Điều này được gọi là "chạy vào cỏ dại".

Tôi chưa bao giờ thấy một cái mà thực sự làm bất cứ điều gì với giá trị được trả về main(). Nếu đây là điều bạn thực sự quan tâm, thì bạn nên xem qua - và có thể sửa đổi - mã nguồn cho thư viện thời gian chạy C của hệ thống.


1
Bạn đánh bại tôi vào nó. +1 cho tính đồng bộ.
Adam Lawrence

9
Tiêu chuẩn C xác định main()để có intgiá trị trả về rõ ràng không được thiết kế với bộ vi điều khiển không có hệ điều hành. Vì vậy, đây là hành vi không xác định và bất cứ điều gì có thể xảy ra tùy thuộc vào thời gian chạy C của bạn, như Dave liệt kê.
ndim

4
C chạy trên một vi điều khiển không có hệ điều hành có thể được coi là một triển khai tự do và tiêu chuẩn C thậm chí không yêu cầu một môi trường tự do để một main()giá trị trả về ít hơn nhiều. Đó là tùy thuộc vào người thực hiện.
KutuluMike

2
@ndim - để chẻ sợi tóc, void main( void )thực hiện hành vi xác định , không phải hành vi không xác định .
Andrew

1
@MichaelEdenfield: Thật vậy. Tuy nhiên, tất cả các mã trong C được định nghĩa theo các hàm, vì vậy không bao giờ có thể có một hệ thống rõ ràng được viết hoàn toàn bằng C; cần phải có ít nhất một chút ngôn ngữ lắp ráp (hoặc bất cứ thứ gì) thiết lập một môi trường tối thiểu để có thể gọi hàm C. Tên rõ ràng nhất cho chức năng đó là main().
Dave Tweed

5

Một hiểu lầm phổ biến / huyền thoại là int mainlà hình thức chỉ có giá trị theo quy định của tiêu chuẩn. Điều đó không đúng.

Tiêu chuẩn C nói về hai triển khai: lưu trữ và tự do. "Thực hiện" trong trường hợp này có nghĩa là trình biên dịch. Trình biên dịch được lưu trữ biên dịch cho một hệ điều hành cụ thể và trình biên dịch tự do biên dịch cho một ứng dụng kim loại trần cụ thể. Các hệ thống nhúng hầu như luôn là các hệ thống độc lập - ngay cả trong trường hợp RTOS.

Việc triển khai tự do có thể sử dụng bất kỳ hình thức nào main(), thậm chí họ không cần phải có một chức năng gọi là chính. Thông thường, họ sử dụng biểu mẫu void main (void), vì nó không có ý nghĩa gì để trả lại bất cứ điều gì.

Điều quan trọng cần nhận ra ở đây là nó luôn là trình biên dịch quyết định hình thức main()và không bao giờ là lập trình viên.

Đơn Lập hiện thực mà làm lại một cái gì đó từ main()rất đáng ngờ. Làm cho bạn tự hỏi nếu những người thực hiện trình biên dịch thực sự đọc tiêu chuẩn ...

Chi tiết tại đây .


3

Tiêu chuẩn ngôn ngữ C cho phép thực hiện biến thể được xác định void main( void )và đây là dạng thông thường trong các hệ thống nhúng - đơn giản vì chúng không được mong đợi quay trở lại.

Nếu bạn nhìn vào thiết lập trình biên dịch, thường có một đoạn mã bootstrap, được gọi từ vector thiết lập lại, thực hiện một số khởi tạo cơ bản (bao gồm cả việc đối phó các giá trị khởi tạo thành các biến) trước khi gọi hàm main ().

Điều này cũng sẽ (thường) nằm trong một vòng lặp vô hạn, hoặc có thể thực hiện thiết lập lại, nếu main()trả về


0

Nó (như các câu trả lời khác được đề cập) phụ thuộc vào chuỗi công cụ của bạn, nhưng ví dụ trong GCC mainđược biên dịch thành các hàm khác, vì vậy giá trị trả về của nó sẽ được lưu trữ theo các quy ước gọi (trên ARM tôi đang sử dụng quyền không phải với GCC, nó sẽ được đưa vào R0 ngay trước khi trở về).

Tôi đoán đó là simillar trên AVR-GCC, vì vậy tập lệnh tùy chỉnh có thể sử dụng giá trị này sau khi trả về chính.


điều này khá sai điểm
Chris Stratton

Nó nhấn mạnh rằng người gọi maincó thể nhận được giá trị trả về của nó. Tất nhiên nó bị bỏ qua trong 99,9% tình huống, nhưng câu trả lời cung cấp thông tin ai có thể nhận được giá trị trả lại này.
kwesolowski
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.