2012-06-05 39 views
30

thể trùng lặp:
Is main() really start of a C++ program?Gọi một hàm trước khi chính

là có thể gọi hàm của tôi trước khi khởi động chương trình? Làm cách nào tôi có thể thực hiện tác vụ này trong C++ hoặc C?

+16

Có một lý do thuyết phục bạn không thể chỉ thực hiện cuộc gọi ngay sau khi nhập main() nhưng trước khi bất kỳ mã khác của bạn thực hiện? Tại sao yêu cầu trước chính() là? – Omaha

+3

Tại sao không gọi chức năng này khi bắt đầu chính? –

+3

Bạn muốn làm gì? Nếu bạn tiếp tục giải thích vấn đề thực tế của bạn, bạn có thể nhận được đề xuất về thiết kế (chứ không phải là kỹ thuật). Trong khi bạn có thể làm những gì bạn yêu cầu, tôi sẽ suy nghĩ lại một thiết kế phụ thuộc vào điều này. –

Trả lời

38

Bạn có thể có biến toàn cục hoặc một thành viên lớp học static.

1) static lớp thành viên

//BeforeMain.h 
class BeforeMain 
{ 
    static bool foo; 
}; 

//BeforeMain.cpp 
#include "BeforeMain.h" 
bool BeforeMain::foo = foo(); 

2) toàn cầu biến

bool b = foo(); 
int main() 
{ 
} 

Lưu ý liên kết này - Mirror of http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14/proposed alternative - đăng bởi Lundin.

+4

Lưu ý: bản thân lớp 'là giả mạo ở đây, chỉ cần xây dựng một toàn cầu (bất cứ điều gì) là đủ. –

+3

Chỉ cần biết [lỗi tinh tế này] (http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14). Hàm được gọi không thể được phép phụ thuộc vào bất kỳ tài nguyên tĩnh nào. Bạn nên viết nó như là bạn sẽ viết một hàm re-entrant. – Lundin

+0

Tôi tin rằng điều này là không chính xác về mặt kỹ thuật. AFAIR chức năng không bắt buộc phải được gọi trước 'main' và có thể bị trì hoãn cho đến khi' b' là cần thiết. Hoặc có thể đó chỉ là trạng thái quan sát được giống nhau. – Pubby

25

Trong C++ có một phương pháp đơn giản: sử dụng hàm tạo của đối tượng chung.

class StartUp 
{ 
public: 
    StartUp() 
    { foo(); } 
}; 

StartUp startup; // A global instance 

int main() 
{ 
    ... 
} 

Điều này vì đối tượng chung được xây dựng trước khi main() bắt đầu. Khi Lundin chỉ ra, hãy chú ý đến số static initialization order fiasco.

+0

Bất kỳ phần nào của quá trình khởi tạo, thực sự, kể cả các đối số được truyền cho một hàm tạo. –

+4

Chỉ cần biết [lỗi tinh tế này] (http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14). Hàm được gọi không thể được phép phụ thuộc vào bất kỳ tài nguyên tĩnh nào. Bạn nên viết nó như là bạn sẽ viết một hàm re-entrant. – Lundin

11

Trong C++, có thể, ví dụ:

static int dummy = (some_function(), 0); 

int main() {} 

Trong C, điều này không được phép vì trình khởi tạo cho các đối tượng có thời lượng lưu trữ tĩnh phải là biểu thức không đổi.

+0

Trong C không có cách nào? Chỉ trong C++? – Nick

+0

@Nick: vâng, theo như tôi biết. –

+2

@CharlesBailey: Bạn cũng có thể làm cho nó hoạt động trong C: 'static size_t dummy = sizeof (some_function(), 0);' – Nawaz

14

Nếu sử dụng gccg++ trình biên dịch thì đây có thể được thực hiện bằng cách sử dụng __attribute__((constructor))

ví dụ ::
Trong gcc (c) ::

#include <stdio.h> 

void beforeMain (void) __attribute__((constructor)); 

void beforeMain (void) 
{ 
    printf ("\nbefore main\n"); 
} 

int main() 
{ 
printf ("\ninside main \n"); 
return 0; 
} 

Trong g ++ (C++) ::

#include <iostream> 
using namespace std; 
void beforeMain (void) __attribute__((constructor)); 

void beforeMain (void) 
{ 
    cout<<"\nbefore main\n"; 
} 

int main() 
{ 
    cout<<"\ninside main \n"; 
    return 0; 
} 
+7

Ngoại trừ trường hợp này không phải là C và C++, đó là các tiện ích mở rộng không chuẩn của GCC. – Lundin

+0

Tôi đã có nhu cầu gọi hàm 'void 'trước chính gần đây và cố gắng điều chỉnh câu trả lời này nhưng đã bị lỗi. Tôi đã thử nghiệm tại cpp.sh cũng như đầu bếp mã: cùng một kết quả cả hai trường hợp. Nếu tôi sử dụng printf thay vì cout, không có sự cố. Bất kỳ ý tưởng tại sao? – StoneThrow

2

Tôi khuyên bạn nên tham khảo liên kết này ..

http://bhushanverma.blogspot.in/2010/09/how-to-call-function-before-main-and.html

Đối với trình biên dịch GCC trên Linux/Solaris:

#include 

void my_ctor (void) __attribute__ ((constructor)); 
void my_dtor (void) __attribute__ ((destructor)); 

void 
my_ctor (void) 
{ 
printf ("hello before main()\n"); 
} 

void 
my_dtor (void) 
{ 
printf ("bye after main()\n"); 
} 

int 
main (void) 
{ 
printf ("hello\n"); 
return 0; 
} 

$gcc main.c 
$./a.out 
hello before main() 
hello 
bye after main() 
Các vấn đề liên quan