2013-02-20 17 views
13

मेरे सवालों का:समारोह सूचक समानता

  1. समारोह सूचक समानता सी मानक की गारंटी है?
  2. यदि (1) का उत्तर हाँ है। क्या यह मामला अलग-अलग अंतिम संकलन इकाइयों (जैसे मुख्य निष्पादन योग्य और साझा लाइब्रेरी) में प्राप्त किया जा रहा है?
  3. गतिशील लोडर उस के साथ कैसे व्यवहार करता है? (मैं कुछ कारणों के बारे में सोच सकता हूं जिनके लिए यह मुश्किल हो सकता है, सभी पीआईसी कोड से संबंधित हैं (उदाहरण के लिए एएलएफ में जीओटी टेबल और इसके लिए जो भी समकक्ष सीओएफएफ उपयोग करता है))। भले ही (1) और (2) लिनक्स लोडर इसकी गारंटी देता है।

यहां एक उदाहरण है। ऊपर दिए गए प्रश्न यह बताते हैं कि सी main.c प्रिंट्स की गारंटी देता है: "Function equality: 1" या "Function equality: 0" और, पहले मामले में, डायनामिक लोडर ऐसा कैसे करता है।

common.h:

extern void * getc_main; 
extern void * getc_shared; 
void assign_getc_shared(); 

main.c:

#include <stdio.h> 
#include "common.h" 

int main() 
{ 
    getc_main = (void*) getc; 
    assign_getc_shared(); 
    printf("Function equality: %d\n", getc_main == getc_shared); 
    return 0; 
} 

shared.c:

#include <stdio.h> 
#include "common.h" 

void assign_getc_shared() 
{ 
    getc_shared = (void*) getc; 
} 

यूनिक्स में यह निम्न कमांड के साथ संकलित किया जाएगा:

cc -shared -fPIC -o libshared.so shared.c 
cc -o main main.c -L. -lshared 

और साथ निष्पादित:

LD_LIBRARY_PATH=. ./main 
+0

यह पूछने का एक लंबा रास्ता है "क्या यह गारंटी है कि मानक लाइब्रेरी फ़ंक्शंस केवल निष्पादन योग्य में एक बार शामिल हो जाएंगे" –

+0

और मुझे लगता है कि श्री लिस्टर के प्रश्न का उत्तर "नहीं, इसकी गारंटी नहीं है" ।कार्यों को रेखांकित किया जा सकता है, उदाहरण के लिए - और यदि आप इनलाइन फ़ंक्शन का पता लेते हैं, तो इसे कोड में "असली" फ़ंक्शन के रूप में शामिल किया जाएगा, जिसका अर्थ है कि संभावित स्रोत फ़ंक्शन के लिए संभावित रूप से कई फ़ंक्शन होंगे। –

+0

@Mrlister अगर मुझे केवल यह जानने में दिलचस्पी थी, तो मैंने केवल यही पूछा होगा। अतिरिक्त प्रश्न पूछने का कारण यह है कि मुझे इस समस्या से निपटने के तरीके के बारे में जानकारी जानने में दिलचस्पी है। आपकी टिप्पणी से मुझे लगता है कि आप नहीं हैं, और यह ठीक है। – fons

उत्तर

12

सी 2011 (N1570 समिति ड्राफ्ट) 6.5.9 6: "दो संकेत तुलना बराबर यदि और केवल यदि ... दोनों के लिए एक ही ... समारोह संकेत दिए गए हैं ...। तो, हाँ, एक ही फ़ंक्शन के दो पॉइंटर्स बराबर की तुलना करते हैं।

जब किसी फ़ंक्शन का पता दो अलग-अलग ऑब्जेक्ट मॉड्यूल में लिया जाता है, तो कंपाइलर ऑब्जेक्ट कोड में प्लेसहोल्डर रखता है। उस प्लेसहोल्डर को तब भर दिया जाता है जब ऑब्जेक्ट मॉड्यूल निष्पादन योग्य में जुड़े होते हैं या रन-टाइम पर गतिशील लाइब्रेरी से जुड़े होते हैं।

गतिशील पुस्तकालयों के लिए, या तो डायनामिक लोडर सभी प्लेसहोल्डर में आवश्यकतानुसार निष्पादन योग्य में भरता है या प्रत्येक फ़ंक्शन का पता वास्तव में कुछ स्टब कोड का स्थान होता है जो वास्तविक फ़ंक्शन पर कूदता है, और उस प्लेसहोल्डर में या उसके द्वारा उपयोग किया जाता है स्टब कोड गतिशील लोडर द्वारा भरा जाता है।

इसके अतिरिक्त, ध्यान दें कि निष्पादन योग्य में फ़ंक्शन के एक से अधिक उदाहरण हो सकते हैं। कंपाइलर कई जगहों या मई में फ़ंक्शन इनलाइन को अपने स्वयं के कारणों से सम्मिलित कर सकता है, इसमें फ़ंक्शन के साथ-साथ एक सामान्य संस्करण भी शामिल है। हालांकि, जब समारोह का पता लिया जाता है, तो संकलक को एक सामान्य संस्करण का पता प्रदान करना होगा। (या संकलक को यह सुनिश्चित करना चाहिए कि प्रोग्राम ऐसा व्यवहार करता है जैसे कि किया गया था। उदाहरण के लिए, यदि संकलक यह पता लगा सकता है कि प्रोग्राम पॉइंटर्स की तुलना नहीं करता है, तो यह सिद्धांत रूप में, पते के कुछ उदाहरणों के लिए एक अलग पता का उपयोग करने में सक्षम हो सकता है फ़ंक्शन का।)

+0

इसका मतलब है कि 80x86 वास्तविक मोड पर सी 2011 अनुरूप सी संकलक को कार्यान्वित करना असंभव है। चूंकि मेमोरी में किसी भी बिंदु को 4096 अलग-अलग (दूर/विशाल) पॉइंटर्स के माध्यम से एक्सेस किया जा सकता है। –

+4

@tristopia: मैं नहीं देखता कि आपका निष्कर्ष कैसे चलता है। तथ्य यह है कि प्रत्येक पते में 40 9 6 संभावित प्रस्तुतियां संकलक को यह सुनिश्चित करने से नहीं रोकती हैं कि एक ही पते के विभिन्न प्रतिनिधित्व बराबर तुलना करें। संकलक को एक निर्देश के साथ 'a == b' लागू करने की आवश्यकता नहीं है; यह 'ए' और' बी 'में से प्रत्येक को किसी भी अद्वितीय प्रारूप में परिवर्तित करने के लिए अंकगणित करने के लिए स्वतंत्र है और फिर परिणामस्वरूप पूर्ण पते की तुलना करने के लिए स्वतंत्र है। –

+3

इसके अतिरिक्त, कंपाइलर के पास पते लेने पर नियंत्रण होता है, इसलिए यह सुनिश्चित कर सकता है कि फ़ंक्शन पते का एक विशेष प्रतिनिधित्व उपयोग किया जाता है और अन्य नहीं हैं। –

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