2012-01-03 41 views
20

Trong ngôn ngữ hướng đối tượng (C++), bạn có thể thực thi mã trước main() bằng cách sử dụng đối tượng toàn cục hoặc đối tượng tĩnh lớp và yêu cầu hàm tạo của họ chạy mã bạn muốn.Thực thi mã trước chính()

Có cách nào để thực hiện việc này trong C không? Tôi không có bất kỳ vấn đề cụ thể tôi đang cố gắng để giải quyết, tôi chỉ tò mò. Một điều này có thể hữu ích cho việc tự động khởi tạo một thư viện.

+0

http://stackoverflow.com/questions/949890/how-can-i-perform-pre-main-initialization-in-cc-with-avr-gcc – stacker

+0

@stacker - Câu hỏi mà bạn đề cập cụ thể là Môi trường Arduino. Dù sao, câu trả lời có thể hữu ích. – mouviciel

Trả lời

10

Có nhiều cách sử dụng __attribute__ nhưng chúng rất cụ thể đối với trình biên dịch và mã được viết bằng cách sử dụng các số này là không phải là thực sự di động. Mặt khác, ngôn ngữ C không cung cấp bất kỳ mô-đun/thư viện khởi động nào.

Trong C, logic main() là chức năng đầu tiên được gọi bởi hệ điều hành. Nhưng trước khi gọi main(), hệ điều hành gọi một hàm khác được gọi là start-up mô-đun để thiết lập các biến môi trường khác nhau, khởi tạo (không khởi tạo) biến tĩnh, xây dựng khung ngăn xếp (kích hoạt bản ghi) và khởi tạo ngăn xếp ngăn xếp để bắt đầu vùng ngăn xếp và các nhiệm vụ phải được thực hiện trước khi gọi main().

Giả sử bạn đang viết mã cho các hệ thống nhúng nơi không có hệ điều hành nào tối thiểu để thực hiện công việc được đề cập ở trên, thì bạn nên khám phá các tùy chọn này phụ thuộc vào trình biên dịch. Ngoài các trình biên dịch GCC, Turbo-C và Microsoft C cung cấp các tiện ích để thêm mã vào một máy phần cứng cụ thể (ví dụ: 8086 máy).

IOW, các mô-đun khởi động không dành cho các lập trình viên.

+0

Sai, 'main' không phải là chức năng đầu tiên được gọi bởi hệ điều hành. Bạn đã nghe nói về [crt0] (https://en.wikipedia.org/wiki/Crt0) chưa? '_start' luôn được gọi trước' main' và trong Windows, 'WinMain' cũng được gọi trước' main'. –

0

Bạn có thể khởi tạo biến toàn cục nhưng không thể thực hiện chức năng gọi trong các lần khởi tạo này.

1

Không, bạn không thể làm điều đó trong C và tôi cho rằng bạn thực sự không thể nhận được "mã để thực thi trước main()" ngay cả trong C++. Có, có thể xuất hiện trước main() trong tập lệnh, nhưng main() là nơi chương trình thực sự bắt đầu.

Bây giờ, bạn có thể khởi tạo giá trị, điều đó là có thể. Bạn cũng có thể có các biến với trạng thái được đặt trước, nhưng điều đó không giống nhau.

+3

Mỗi 3.6.2/3 ("nó sẽ xảy ra trước lần sử dụng đầu tiên của bất kỳ hàm hoặc đối tượng nào được định nghĩa trong cùng một đơn vị dịch như đối tượng được khởi tạo"), đối tượng có phạm vi không gian tên trong cùng TU như 'main' phải được khởi tạo trước câu lệnh đầu tiên của 'main', vì' main' * là * một hàm trong cùng một TU. Tiêu chuẩn này không quan tâm liệu có một lời gọi tới mã init đó từ bên trong thân hàm của 'main', trước bất kỳ câu lệnh nào khác hay không, hoặc có một số hàm khác để thực hiện init hay không, thực hiện cuộc gọi trước khi nó gọi chính. –

4

Với gcc, bạn có thể làm như vậy bằng cách sử dụng thuộc tính hàm hàm dựng, ví dụ:

__attribute__ ((__constructor__)) 
void foo(void) { 
     ... 
} 

Điều này sẽ gọi foo trước chính.

Lưu ý: Điều này có thể không di động với các trình biên dịch khác.

13

Bạn có thể làm điều đó với __attribute__ ((constructor)). Tôi đã thử nghiệm ví dụ sau với cả hai gccclang. Điều đó đang được nói, đó là không phải là một phần của ngôn ngữ.

#include <stdio.h> 

void __attribute__ ((constructor)) premain() 
{ 
    printf("premain()\n"); 
} 

int main(int argc, char *argv[]) 
{ 
    printf("main()\n"); 
    return 0; 
} 

Nó làm như sau:

$ ./test 
premain() 
main() 
0

Không có trong bất kỳ cách nào đạt tiêu chuẩn, nhưng bạn nên đào trong những gì thực sự xảy ra khi hệ điều hành của bạn tải các hình ảnh nhị phân và gọi hàm chính ứng dụng !

0

Có các cách di động để chỉ định các hàm có thể được thực thi "sau khi" chính được thực hiện.

  1. atexit()

  2. at_quick_exit()

Hơn nữa, hãy làm theo this liên kết và về nhiều loại hình khởi tạo trong C++ - có thể hữu ích cho bạn để thực thi mã trước main() được gọi là .

+0

Hơn nữa, hãy làm theo [link] này (http://en.cppreference.com/w/cpp/language/initialization) và về các kiểu khởi tạo khác nhau trong C++ - có thể hữu ích để bạn thực thi mã trước khi hàm main() là gọi là. –

+0

Câu hỏi đặt ra là gọi mã trước mã chính trong C. Không gọi mã sau mã chính hoặc C++. –

Các vấn đề liên quan