2010-07-06 8 views
12

संभव डुप्लिकेट:
Are there gotchas using varargs with reference parametersvarargs (va_list va_start) पास-दर-संदर्भ पैरामीटर के साथ काम नहीं करता है

हाय, मैं varargs साथ एक समस्या है। मेरा कोड देखें (माइक्रोसॉफ्ट विजुअल स्टूडियो 2005 या 2008)।

#include <stdarg.h> 

struct Test { int a; }; 

void T1(int n, ...) { 
va_list args; 
va_start(args, n); 
char* p = va_arg(args, char*); 
va_end(args); 
} 

void T2(Test n, ...) { 
va_list args; 
va_start(args, n); 
char* p = va_arg(args, char*); 
va_end(args); 
} 

void T3(const Test& n, ...) { 
va_list args; 
va_start(args, n); 
char* p = va_arg(args, char*); // p corrupt!! 
va_end(args); 
} 

int _tmain(int argc, _TCHAR* argv[]) { 
const Test t; 
T1(1, "Test1"); 
T2(t, "Test2"); 
T3(t, "Test3"); 
return 0; 
} 

फ़ंक्शन टी 1, टी 2 अच्छी तरह से काम करता है। लेकिन टी 3 समारोह में एक समस्या है। पॉइंटर पी "टेस्ट 3" इंगित नहीं करता है। क्या मैं पास-बाय-रेफरेंस के साथ va_start का उपयोग नहीं कर सकता? अग्रिम धन्यवाद।

+2

यह जी ++ में इच्छित व्यवहार प्रदर्शित करता है, लेकिन इसका वास्तव में इतना मतलब नहीं है, है ना? –

उत्तर

13

आप सी ++ स्टैंडर्ड 18.7/3 के अनुसार va_start साथ संदर्भ का उपयोग नहीं कर सकते हैं:

प्रतिबंध कि हैडर में va_start() मैक्रो के लिए दूसरा पैरामीटर पर आईएसओ सी स्थानों इस अंतर्राष्ट्रीय मानक में अलग हैं। पैरामीटर पार्मन फ़ंक्शन परिभाषा की परिवर्तनीय पैरामीटर सूची में सही पैरामीटर का पहचानकर्ता है (केवल एक से पहले ...)। यदि पैरामीटर पार्मन को फ़ंक्शन, सरणी या संदर्भ प्रकार के साथ घोषित किया गया है, या उस प्रकार के साथ जो संगत नहीं है, जिसके परिणामस्वरूप कोई पैरामीटर नहीं है, तो व्यवहार अपरिभाषित है।

4

संक्षिप्त उत्तर: नहीं, आप ऐसा नहीं कर सकते।

नोट: मैंने पहला जवाब देखा जो मानक उद्धृत करता है लेकिन मेरा मानना ​​है कि यह मेरे परीक्षणों को दिखाने लायक है।

दृश्य 6:: #define va_start(ap,v) (ap = (va_list)&v + _INTSIZEOF(v))

दृश्य 8: #define _crt_va_start(ap,v) (__va_start(&ap, _ADDRESSOF(v), _SLOTSIZEOF(v), \ __alignof(v), _ADDRESSOF(v)))

इस कोड के साथ

:

va_start इस तरह परिभाषित किया गया है

#include <cstdio> 

int main() 
{ 
    char c; 
    char &rc = c; 
    int i; 
    int &ri = i; 

    printf("char ref:%d\n", sizeof(rc)); 
    printf("int ref:%d\n", sizeof(ri)); 

    return 0; 
} 

उत्पादन

char ref:1 
int ref:4 

चूंकि कार्यान्वयन स्तर संदर्भों को स्टैक पर उसी तरह से पारित किया जाता है क्योंकि यह अलग-अलग होता है क्योंकि आकार भिन्न होता है (यह उस मैक्रो की वजह से है जो इस प्रकार के आकार की गणना करता है कि पैरामीटर वास्तव में नहीं है संदर्भ, जो स्थिर नहीं है लेकिन प्रकार के वास्तविक आकार पर निर्भर करता है)।

+1

धन्यवाद। यह दिलचस्प है। :) –

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