2010-02-02 9 views
13

क्या कोई मौका है कि स्टेटिक फ़ंक्शन का मूल्यांकन फ़ाइल स्कोप के बाहर किया जा सकता है। ?अन्य फ़ाइलों में स्टेटिक फ़ंक्शन का उपयोग

+7

यदि आप हेडर फ़ाइल में फ़ंक्शन डालते हैं। फिर प्रत्येक संकलन इकाई में एक स्थिर संस्करण होगा। –

उत्तर

19

यह "पहुंच" से आपका क्या मतलब है इस पर निर्भर करता है। बेशक, फ़ंक्शन को किसी अन्य फ़ाइल में नाम से नहीं कहा जा सकता है क्योंकि यह static एक अलग फ़ाइल में है, लेकिन आपके पास फ़ंक्शन पॉइंटर है।

$ cat f1.c 
/* static */ 
static int number(void) 
{ 
    return 42; 
} 

/* "global" pointer */ 
int (*pf)(void); 

void initialize(void) 
{ 
    pf = number; 
} 
$ cat f2.c 
#include <stdio.h> 

extern int (*pf)(void); 
extern void initialize(void); 

int main(void) 
{ 
    initialize(); 
    printf("%d\n", pf()); 
    return 0; 
} 
$ gcc -ansi -pedantic -W -Wall f1.c f2.c 
$ ./a.out 
42 
12

नहीं, जब तक कि कंपाइलर में कोई बग न हो। आम तौर पर स्थैतिक फ़ंक्शन कोड को ऑब्जेक्ट फ़ाइल में फ़ंक्शन को निर्यात करने के लिए उपयोग किए गए नाम से टैग नहीं किया जाता है, इसलिए यह लिंकर को प्रस्तुत नहीं किया जाता है और यह केवल उससे लिंक नहीं हो सकता है।

यह निश्चित रूप से केवल नाम से फ़ंक्शन को कॉल करने पर लागू होता है। एक ही फ़ाइल के भीतर अन्य कोड फ़ंक्शन पता प्राप्त कर सकते हैं और इसे किसी अन्य फ़ाइल में एक गैर स्थैतिक फ़ंक्शन में पास कर सकते हैं और फिर किसी अन्य फ़ाइल से फ़ंक्शन आपके स्थिर फ़ंक्शन को कॉल कर सकता है।

4

मानक के बाद, फ़ाइल के दायरे के बाहर एक स्थिर फ़ंक्शन को नाम से एक्सेस नहीं किया जा सकता क्योंकि यह आंतरिक संबंध के अधीन है। इसका नाम निर्यात नहीं किया गया है, और लिंकर को प्रदान नहीं किया गया है। हालांकि, इसे अभी भी किसी भी अन्य फ़ंक्शन की तरह फ़ंक्शन पॉइंटर द्वारा एक्सेस और कॉल किया जा सकता है।

16

इसे फ़ंक्शन पॉइंटर के माध्यम से दायरे से बाहर कहा जा सकता है।

उदाहरण के लिए, यदि आप था:

static int transform(int x) 
{ 
    return x * 2; 
} 

typedef int (*FUNC_PTR)(int); 

FUNC_PTR get_pointer(void) 
{ 
    return transform; 
} 

तो दायरे से बाहर एक समारोह) get_pointer (फोन और लौट आए समारोह सूचक का उपयोग बदलने के कॉल करने के लिए कर सकते हैं।

+1

मुझे लगता है कि "int (* get_pointer (int) होना चाहिए (शून्य)"। – paxdiablo

+0

@ पक्सडीब्लो और @ कैफ - धन्यवाद। –

1

नहीं है, कीवर्ड स्थिर करने के उद्देश्य से फाइल करने के लिए समारोह नाम के दायरे को सीमित करने के लिए है।

6

इसे किसी फ़ाइल के बाहर इसके नाम से एक्सेस नहीं किया जा सकता है। लेकिन, आप इसे पॉइंटर फ़ंक्शन करने के लिए भी असाइन कर सकते हैं और जहां भी चाहें इसका उपयोग कर सकते हैं।

3

केवल चालबाजी के साथ। फ़ंक्शन आमतौर पर लिंकर को दिखाई नहीं देता है, इसलिए यह आपको ऐसा करने नहीं देगा।

लेकिन, आप एक ही संकलन इकाई के अंदर एक समारोह प्रदान करता है, तो (स्थिर समारोह के रूप में) जो कि समारोह के पते प्रस्तुत करती है:

main.c में:

#inclde <stdio.h> 
int (*getGet7(void))(void); 
int main (void) { 
     int (*fn)(void) = getGet7(); 
     printf ("Result is: %d\n", fn()); 
     return 0; 
} 

hidden.c में:

static int get7 (void) { 
     return 7; 
} 
int (*getGet7(void)) (void) { 
     return get7; 
} 

इसके परिणामस्वरूप स्थिर कार्य get7 कहा जा रहा है।

pax> gcc -o demo main.c hidden.c ; ./demo 
Result is: 7 
5

"एक्सेस"? यह इस शब्द से आपका क्या मतलब है इस पर निर्भर करता है। मुझे लगता है कि जब आप "स्थैतिक कार्य" कहते हैं तो आप सी ++ में स्थैतिक वर्ग सदस्य कार्यों के विपरीत static (यानी आंतरिक संबंध के साथ घोषित) स्टैंडअलोन फ़ंक्शन घोषित कर रहे हैं, क्योंकि बाद में कहीं से भी obviosly और आसानी से सुलभ है।

अब, एक स्टैंडअलोन फ़ंक्शन घोषित किया गया है static में आंतरिक संबंध है। यह किसी अन्य अनुवाद इकाई से से नहीं हो सकता है।या, इसे अलग-अलग डालने पर, इसे किसी अन्य अनुवाद इकाई से नाम से पर संदर्भित नहीं किया जा सकता है। यदि आपके पास "फ़ाइल स्कोप के बाहर से पहुंच" का अर्थ है, तो नहीं, यह नहीं किया जा सकता है।

हालांकि, अगर अन्य अनुवाद इकाइयां किसी भी तरह उस फ़ंक्शन पर पॉइंटर प्राप्त करती हैं (यानी यदि आप किसी भी तरह से पॉइंटर को उसाइड दुनिया में "रिसाव" करने की अनुमति देते हैं, तो कोई भी अभी भी उस फ़ंक्शन को एक प्रत्यक्ष कॉल करके कॉल कर सकता है और इस प्रकार "इस तक पहुंचें। उदाहरण के लिए, यदि आप घोषित

static void foo_static(void) { 
} 

extern void (*foo_ptr)(void) = foo_static; 

तो किसी अन्य अनुवाद इकाई में उपयोगकर्ता

extern void (*foo_ptr)(void); 
foo_ptr(); 

ऐसा करने में सक्षम हो जाएगा और कॉल अपने foo_static समारोह के लिए जाना जाएगा। मुझे नहीं पता कि इस तरह की पहुंच आपके प्रश्न में "पहुंच" के रूप में योग्य है या नहीं।

संबंधित मुद्दे

 संबंधित मुद्दे