2015-06-24 6 views
19

मुझे पता है कि sizeof कभी भी अपने ऑपरेंड का मूल्यांकन नहीं करता है, सिवाय इसके कि विशिष्ट मामले को छोड़कर ऑपरेंड एक वीएलए है। या, मैं सोचा मुझे पता था।आकार के ऑपरेटिंग में वीएलए और दुष्प्रभाव

void g(int n) { 
    printf("g(%d)\n", n); 
} 

int main(void) { 
    int i = 12; 

    char arr[i]; // VLA 

    (void)sizeof *(g(1), &arr); // Prints "g(1)" 
    (void)sizeof (g(2), arr); // Prints nothing 

    return 0; 
} 

क्या चल रहा है?

बस मामले में, यह Coliru पर जीसीसी 5.1 के साथ संकलित है।

उत्तर

18

ऐसा लगता है कि मुझे पोस्ट करने से पहले दो बार सोचना चाहिए, क्योंकि मैंने ऐसा करने के ठीक बाद मुझे मारा।

sizeof कैसे सूचना का आदान प्रदान Vlas के साथ वास्तव में सही है, तो निम्न बोली की पुष्टि के रूप में की मेरी समझ (धन्यवाद @this!):

6.5.3.4 sizeof और _Alignof ऑपरेटरों
तो संकार्य के प्रकार एक परिवर्तनीय लंबाई सरणी प्रकार है, ऑपरेंड का मूल्यांकन किया जाता है; अन्यथा, ऑपरेंड का मूल्यांकन नहीं किया जाता है और परिणाम एक पूर्णांक निरंतर

यह आश्चर्यजनक (मेरे लिए) व्यवहार का कारण नहीं है।

(void)sizeof (g(2), arr); 

(g(2), arr) उपसूचक में, अल्पविराम ऑपरेटर से चलाता है arr की सरणी-टू-सूचक क्षय। इस प्रकार, sizeof का ऑपरेंड अब वीएलए नहीं है, लेकिन एक सादा char* है, और यह अपने ऑपरेंड का मूल्यांकन नहीं करने के लिए वापस आता है।

Apparently यह व्यवहार सी ++ में बदल दिया गया है, जहां अल्पविराम ऑपरेटर अब सरणी क्षय नहीं करेगा।

+2

एक बार, अपने स्वयं के प्रश्न का उत्तर देने के लिए एक अच्छा मामला। – Bathsheba

+2

आप इसे कहीं कहीं जोड़ना चाहेंगे: * 6.5.3.4 आकार और _Aignignof ऑपरेटरों यदि ऑपरेंड का प्रकार एक चर लंबाई लंबाई प्रकार है, तो ऑपरेंड का मूल्यांकन किया जाता है; अन्यथा, ऑपरेंड का मूल्यांकन नहीं किया जाता है और नतीजा पूर्णांक निरंतर होता है। * इसलिए बुखार पाठकों को भ्रमित कर दिया जाएगा। – this

+0

@ यह धन्यवाद :) – Quentin

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