हाल ही में, हमने कुछ पुराने कोड में अजीब व्यवहार की खोज की। इस कोड ने उम्र के लिए काम किया है, लेकिन कुछ प्लेटफ़ॉर्म (एक्सबॉक्स 360, पावरपीसी) पर संकुचित किया गया है जिसमें अधिकतम संकलक ऑप्टिमाइज़ेशन चालू हो गए हैं। आमतौर पर, मुझे अपरिभाषित व्यवहार पर संदेह होगा।क्या एक अनुरूप कंपेलर uint32_t -> int16_t -> int32_t रूपांतरण तोड़ सकता है?
कोड इस तरह मोटे तौर पर दिखता है:
#include <stdint.h>
uint32_t sign_extend16(uint32_t val)
{
return (int32_t)(int16_t)val;
}
तो सवाल में आपरेशन भी अजीब नहीं होना चाहिए यह एक एमुलेटर का हिस्सा है। आम तौर पर, मैं उम्मीद करता हूं कि यह केवल निम्न 16-बिट्स पर विचार करे और 32-बिट्स तक साइन-विस्तार करें। जाहिर है, यह वही व्यवहार था जो उम्र के लिए था। x86_64 पर, जीसीसी मुझे इस परिणाम देता है:
0000000000000000 <sign_extend16>:
0: 0f bf c7 movswl %di,%eax
3: c3 retq
हालांकि, मैं क्या मानक की समझ सकते हैं, एक हस्ताक्षरित परिभाषित नहीं है करने के लिए एक अहस्ताक्षरित रूपांतरित होने से इसके साथ अहस्ताक्षरित एक के मूल्य का प्रतिनिधित्व करने के लिए संभव नहीं होना चाहिए हस्ताक्षरित प्रकार।
क्या यह संकलक के लिए यह संभव हो सकता है कि हस्ताक्षर किए गए मान को [0, 32767]
की सीमा में होना चाहिए, क्योंकि कोई अन्य मूल्य अपरिभाषित होगा? उस स्थिति में, int16_t
पर एक कास्ट और अभी तक int32_t
पर एक और कलाकार कुछ भी नहीं करेगा। इस मामले में, क्या संकलक के लिए कोड को सरल स्थान पर अनुवाद करना कानूनी होगा?
'(int16_t) val' का व्यवहार कभी अपरिभाषित नहीं होता है। इसका व्यवहार अच्छी तरह से परिभाषित किया गया है यदि 'val'' int16_t' के रूप में प्रतिनिधित्व योग्य है, अन्यथा व्यवहार कार्यान्वयन-परिभाषित है। –
@ मैस्टर x86_64 पर आपके पास वास्तव में क्या समस्या है? 'movswl' निर्देश साइन एक्सटेंशन करता है। जब आप मूल्य 32768 पास करते हैं तो आपके पास क्या परिणाम है? 'जीसीसी' के साथ आपके 32-बिट/64-बिट सिस्टम पर, वापसी मान '0xFFFF8000' होना चाहिए। – ouah
शायद मैं पर्याप्त स्पष्ट नहीं हो सकता था। X86_64 पर व्यवहार की अपेक्षा की जाती है। हालांकि यह xbox 360 पर अपेक्षित कार्य नहीं करता है। – Maister