2012-11-18 10 views
5

संभव डुप्लिकेट:
Casting a function pointer to another typeसी में फंक्शन पॉइंटर कानूनी/परिभाषित के माध्यम से अतिरिक्त पैरामीटर पास कर रहा है?

मान लें मैं प्रारंभ एक समारोह है कि वास्तव में कम मानकों तो समारोह सूचक परिभाषा लेता है के साथ एक समारोह सूचक, समारोह अभी भी सही ढंग प्रदर्शन करेंगे, तो कहा जाता है के माध्यम से फंक्शन पॉइंटर?

मैं जीसीसी के साथ इस की कोशिश की और यह उम्मीद के रूप में काम किया, लेकिन मैं आश्चर्य है कि अगर उस व्यवहार के पार compilers/प्लेटफार्मों संगत (मैं कुछ वातावरण में संदेह है कि यह ढेर पर कहर ढ़ा हो सकता है) है:

#include <stdio.h> 

typedef void (*myfun)(int, int, int); 

void test_a(int x, int y, int z) { 
    printf("test_a %d %d %d\n", x, y, z); 
} 

void test_b(int x, int y) { 
    printf("test_b %d %d\n", x, y); 
} 

int main() { 
    myfun fp; 
    fp = test_a; 
    fp(1, 2, 3); 
    fp = (myfun) test_b; 
    fp(4, 5, 6); 
} 

उत्तर

4

आपके कार्यक्रम का व्यवहार अपरिभाषित है। तथ्य यह है कि यह सभी का संकलन कलाकारों के कारण होता है, जो प्रभावी ढंग से संकलक को बताता है "यह गलत है, लेकिन वैसे भी इसे करें"। आप वर्णक निकालने हैं, तो आप उचित त्रुटि संदेश मिल जाएगा: (। gcc -Wall -Werror से)

a.c:17:8: error: assignment from incompatible pointer type [-Werror] 

अधिक विशेष रूप से, व्यवहार बुला सम्मेलनों पर निर्भर करता है। यदि आप मंच पर थे तो तर्क स्टैक पर "रिवर्स" ऑर्डर में पारित किए गए थे, कार्यक्रम एक बहुत अलग परिणाम देगा।

+1

यदि कैली क्लीन-अप का उपयोग किया जाता है तो यह भी क्रैश हो सकता है। –

+0

मैं देखता हूं। पैरामीटर सूची के बिना फ़ंक्शन पॉइंटर प्रकार को परिभाषित करने के बारे में क्या, जैसे'typedef void (* myfun)() '। क्या संकलक को उस मामले में "दाएं" होने के लिए स्टैक पर पैरामीटर के आदेश की गारंटी देना चाहिए? – Askaga

+0

@ बिलशास्का नहीं: आप जो चाहते हैं उसे "गारंटी" करने के लिए, आपको यह सुनिश्चित करने की आवश्यकता हो सकती है कि लक्ष्य फ़ंक्शन और आपका फ़ंक्शन पॉइंटर दोनों [सीडीईसी कॉलिंग कन्वेंशन] का उपयोग करें (http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl)। – ChrisW

10

यह अपरिभाषित व्यवहार है। अपने जोखिम पार इस्तेमाल करें। यह Nasal Demons!

enter image description here

+0

यह छवि कमाल है। यहां मैं एक साफ संस्करण और एक वेक्टर ट्रेस प्रदान करता हूं: https://www.dropbox.com/sh/c0f5htyg46jcels/AABD9Qaw2JlhMAKCycAek-9ia?dl=0 – wilx

+0

लॉल। धन्यवाद।मैंने अपनी पसंदीदा बेटी को अपरिभाषित व्यवहार के बारे में कहानी सुनाई जो डूडल करना पसंद करता है। उसने मुझे अगले दिन यह भेजा। इसके बारे में प्यार करने के लिए बस इतना कुछ है। – EvilTeach

+0

यहां जेपीजी है: http://imgur.com/gallery/Zomm1zq/new – wilx

2

पैदा करने के लिए क्या यह काम करता है calling convention पर निर्भर करेगा इस्तेमाल किया जा रहा अफवाह कर दिया गया है।

मैं इसकी अनुशंसा नहीं करता।

3

फ़ंक्शन कॉल अपरिभाषित व्यवहार है।

(सी 99, 6.3.2.3 पी 8) "[...] यदि एक परिवर्तित पॉइंटर का उपयोग किसी फ़ंक्शन को कॉल करने के लिए किया जाता है जिसका प्रकार बिंदु-प्रकार के साथ संगत नहीं है, तो व्यवहार अपरिभाषित है।"

जानकारी नोट के लिए है कि एक समारोह प्रकार:

(C99, 6.2.5p20) "[...] निर्दिष्ट वापसी प्रकार के साथ एक समारोह का वर्णन एक समारोह प्रकार की विशेषता है। इसका रिटर्न प्रकार और इसके पैरामीटर की संख्या और प्रकार। "

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