Tôi đi qua this question hỏi cách thực thi mã trước main() trong C, đề cập đến các chiến lược cho C++. Tôi đã chủ yếu sống trong không gian ứng dụng, vì vậy thực hiện trước khi main() chưa bao giờ xảy ra với tôi. Những thứ gì đòi hỏi kỹ thuật này?Loại hoạt động nào có thể cần thực hiện trước khi chính()
Trả lời
"Loại thứ gì yêu cầu kỹ thuật này?"
Điểm thực tế: không.
Tuy nhiên, có rất nhiều điều hữu ích bạn có thể muốn làm trước khi chính vì nhiều lý do. Chỉ với một ví dụ thực tế, giả sử bạn có một nhà máy trừu tượng xây dựng các doohickies. Bạn có thể chắc chắn để xây dựng trường hợp nhà máy, gán nó cho một số khu vực đặc biệt, và sau đó đăng ký các doohickies bê tông khác nhau để nó ... có, bạn có thể làm điều đó. Mặt khác, nếu bạn thực hiện nhà máy như một singleton và sử dụng sự kiện khởi tạo giá trị toàn cầu để "lừa" việc thực hiện đăng ký doohickies cụ thể trước khi bắt đầu chính bạn có được nhiều lợi ích với rất ít chi phí (thực tế của sử dụng singletons, về cơ bản không phải là vấn đề ở đây, là khá nhiều người duy nhất).
Ví dụ bạn:
Đừng có để duy trì một danh sách đăng ký mà tất cả phải được gọi một cách rõ ràng. Trong thực tế, bạn thậm chí có thể khai báo và định nghĩa toàn bộ một lớp trong phạm vi riêng tư, ngoài tầm nhìn của bất kỳ ai và có sẵn để sử dụng khi chương trình bắt đầu.
chính() không phải làm một loạt các crap với một loạt các đối tượng mà nó không quan tâm.
Vì vậy, không ai trong số này thực sự là cần thiết. Tuy nhiên, bạn có thể giảm các vấn đề về ghép nối và bảo trì nếu bạn tận dụng thực tế là các hình cầu được khởi tạo trước khi bắt đầu chính.
Chỉnh sửa:
Cần lưu ý rằng tôi đã biết rằng điều này không được ngôn ngữ đảm bảo.C++ chỉ đảm bảo rằng số không hoặc hằng số khởi chạy diễn ra trước chính. Những gì tôi nói về câu trả lời này là động khởi tạo. Việc bảo đảm C++ này xảy ra trước khi sử dụng biến đầu tiên, giống như các biến tĩnh cục bộ của hàm.
Mọi trình biên dịch mặc dù dường như khởi tạo động trước khi chính. Tôi nghĩ rằng tôi đã gặp một lần nhưng điều đó không đúng nhưng tôi tin rằng nguồn gốc của vấn đề là một thứ khác.
+1, đây là sử dụng duy nhất tôi có cho điều này ... nhưng cậu bé để tôi sử dụng nó! –
Kỹ thuật này có thể được sử dụng cho các thường trình khởi tạo thư viện hoặc để khởi tạo dữ liệu sẽ được sử dụng ngầm trong khi thực hiện chương trình.
GCC cung cấp constructor và destructorfunction attributes gây một chức năng để tự động được gọi trước khi thực hiện bước vào main()
hoặc main()
đã hoàn thành hoặc exit()
đã được gọi là, tương ứng.
void __attribute__ ((constructor)) my_init(void);
void __attribute__ ((destructor)) my_fini(void);
Trong trường hợp khởi tạo thư viện, thói quen xây dựng được thực hiện trước khi dlopen()
lợi nhuận nếu thư viện được nạp trong thời gian chạy hoặc trước main()
được bắt đầu nếu thư viện được nạp tại thời gian tải. Khi được sử dụng để dọn dẹp thư viện, các thói quen hủy được thực thi trước khi trả về dlclose()
nếu thư viện được tải vào thời gian chạy hoặc sau exit()
hoặc hoàn thành main()
nếu thư viện được tải vào thời gian tải.
Nếu bạn có thư viện, rất thuận tiện để có thể khởi tạo một số dữ liệu, tạo chuỗi v.v. trước khi hàm main() được gọi và biết rằng trạng thái mong muốn đạt được mà không cần phải gánh nặng và tin tưởng ứng dụng khách một cách rõ ràng gọi một số thư viện initialisation và/hoặc tắt mã. Bề ngoài, điều này có thể đạt được bằng cách có một đối tượng tĩnh có constructor và destructor thực hiện các hoạt động cần thiết. Thật không may, nhiều đối tượng tĩnh trong các đơn vị dịch thuật hoặc thư viện khác nhau sẽ có thứ tự khởi tạo không xác định, vì vậy nếu chúng phụ thuộc vào nhau (tệ hơn, theo kiểu cyclic), thì chúng vẫn chưa đạt được trạng thái khởi tạo của chúng trước khi yêu cầu đến Tương tự như vậy, một đối tượng tĩnh có thể tạo ra các luồng và các dịch vụ cuộc gọi trong một đối tượng khác chưa được tạo luồng. Vì vậy, một cách tiếp cận có cấu trúc hơn với trường hợp singleton thích hợp và ổ khóa là cần thiết cho sự vững mạnh khi đối mặt với việc sử dụng tùy ý, và toàn bộ điều có vẻ hấp dẫn hơn nhiều, mặc dù nó vẫn có thể là một chiến thắng ròng trong một số trường hợp.
Stuff thực hiện trước khi chính:
- Trên x86, con trỏ thanh ghi chồng thường là & = 0XF3 để làm cho nó một bội số của 4 (alignment)
- thành viên tĩnh được khởi tạo
- đẩy argc và argv (và environ nếu cần)
- gọi _main = p
g ++ 4.4 phát ra BEF sau quặng bất kỳ mã nào của tôi được phát ra. Về mặt kỹ thuật nó chèn nó vào đầu main
trước khi bất kỳ mã của tôi, nhưng tôi đã nhìn thấy các trình biên dịch sử dụng _init
thay vì _main
như điểm mấu chốt:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
# My code follows
Những điều duy nhất bạn có thể muốn làm trước khi main
liên quan các biến toàn cầu, điều xấu, và những thứ tương tự luôn có thể được thực hiện bằng cách khởi tạo lười (khởi tạo tại điểm sử dụng đầu tiên). Tất nhiên họ sẽ được thực hiện tốt hơn nhiều bằng cách không sử dụng các biến toàn cục.
Một "ngoại lệ" có thể là khởi tạo các bảng hằng số chung khi chạy. Nhưng đây là một thực tế rất xấu, vì các bảng không thể chia sẻ giữa các cá thể của một thư viện/quá trình nếu bạn điền chúng vào thời gian chạy. Sẽ là thông minh hơn khi viết kịch bản để tạo các bảng static const
dưới dạng tệp nguồn C hoặc C++ tại thời gian xây dựng.
Mọi thứ cần chạy mã để đảm bảo bất biến cho mã của bạn sau khi main
bắt đầu chạy trước main
. Những thứ như iostreams toàn cầu, thư viện thời gian chạy trên C, liên kết hệ điều hành, v.v.
Bây giờ bạn có thực sự cần viết mã thực hiện những điều như vậy hay không là những gì mọi người khác đang trả lời.
- 1. JPA thực thể loại bỏ hoạt động không thực hiện
- 2. Thực hiện lệnh in cmake trước khi thực hiện
- 3. Làm cách nào để thực hiện hoạt ảnh mờ dần khi chuyển đổi Hoạt động?
- 4. cách thực hiện {} trong khi (0) hoạt động trong macro?
- 5. Thực hiện hoạt động mới xuất hiện phía sau hoạt động cũ trong khi chuyển đổi
- 6. Truy vấn Echo trước khi thực thi và không được thực hiện trong trình mã hóa Bản ghi Hoạt động
- 7. Khi nào tôi cần thực hiện "git pull", trước hoặc sau "git add, git commit"?
- 8. ASP.Net MVC "Không thể tải loại" khi thực hiện
- 9. Có thể loại trừ các cam kết cụ thể khi thực hiện hợp nhất git không?
- 10. Thực thi mã trước chính()
- 11. "Hoạt động động chỉ có thể được thực hiện trong AppDomain đồng nhất" lỗi
- 12. Làm thực hiện lệnh in trước khi thực hiện khi không sử dụng CMake
- 13. Chuyển đến màn hình chính thay vì Hoạt động trước
- 14. Làm thế nào tôi có thể thực hiện khởi tạo trước chính trong C/C++ với avr-gcc?
- 15. .NET có thể hoạt động tốt mà không cần sử dụng loại Object không?
- 16. Thực thi mã trên chuỗi chính trong Android mà không cần truy cập vào Hoạt động?
- 17. Sau khi loại ngoại lệ/lỗi nào xảy ra khi cá thể Azure Cloud thực hiện khởi động lại?
- 18. Có bảo hành tự động xả trước khi thoát không? Làm thế nào nó hoạt động?
- 19. Django caching - nó có thể được thực hiện trước khi emptively?
- 20. Thực hiện một hoạt động cụ thể dưới dạng hoạt động gốc trong ngăn xếp
- 21. Làm thế nào tôi có thể nhận được jquery để thực hiện hình ảnh động song song chính xác?
- 22. Tải hoạt động trong nền trước khi hiển thị nó
- 23. Có cách nào để xác minh mã đó sẽ hoạt động trên 360 trong khi thực hiện XNA dev không?
- 24. Cách thực hiện: render => không có gì hoạt động
- 25. "hoạt động động chỉ có thể được thực hiện trong appdomain đồng nhất" lỗi trong khi tung ra PowerShell
- 26. Làm cách nào để tôi có thể thực hiện JSP khi biên dịch Tomcat khi khởi động?
- 27. Thực hiện kiểm tra trước khi khởi tạo danh sách
- 28. editText trước khi chuyển sang Hoạt động khác
- 29. sẽ thoát khỏi luồng chính trước khi các chuỗi con hoàn thành quá trình thực hiện?
- 30. Tài nguyên góc có thể thực hiện hoạt động yên tĩnh không?
Những điều không nên làm. –
Điều này thật thú vị: http: // stackoverflow.com/questions/4783404/là-chính-thực sự-bắt đầu-of-a-c-chương trình – Dave