2010-12-12 13 views
12

द्वारा संरेखित प्रकार और गुजरने वाले तर्क मूल्य से गठबंधन प्रकारों के साथ गठबंधन प्रकार या संरचनाओं को पास करना कुछ कार्यान्वयन के साथ काम नहीं करता है। यह एसटीएल कंटेनर तोड़ता है, क्योंकि कुछ विधियों (जैसे आकार बदलने) उनके तर्कों को मूल्य से लेते हैं।मूल्य

मैं विजुअल स्टूडियो 2008 के साथ कुछ परीक्षण चलाता हूं और पूरी तरह से सुनिश्चित नहीं करता कि मूल्य कब और कैसे विफल हो जाता है। मेरी मुख्य चिंता foo है। ऐसा लगता है कि यह ठीक काम करता है, लेकिन क्या यह इनलाइनिंग या कुछ अन्य संयोग का परिणाम हो सकता है? क्या होगा अगर मैं शून्य फू (कॉन्स्ट __m128 &) पर अपना हस्ताक्षर बदलूं?

आपके इनपुट की बहुत सराहना की जाती है। धन्यवाद।

struct A 
{ 
    __m128 x; 
    int n; 
}; 

void foo(__m128); 
void bar(A); 

void f1() 
{ 
    // won't compile 
    // std::vector<A> vec1(3); 

    // compiles, but fails at runtime when elements are accessed 
    std::vector<__m128> vec2(3); 

    // this seems to work. WHY??? 
    std::vector<__m128, some_16_byte_aligned_allocator<__m128> > vec3(3); 

    __m128 x; 
    A a; 

    // passed by value, is it OK? 
    foo(x); 

    // won't compile 
    //bar(a); 
} 

संपादित करें। एसटीएल गठबंधन आवंटक के साथ भी विफल रहता है, क्योंकि मूल्य समस्या से गुजरती रहती है।

इस लिंक pass __m128 by value

+0

आपके द्वारा प्राप्त संकलन त्रुटियों/चेतावनियां क्या हैं? मुझे लगता है जैसे "औपचारिक पैरामीटर ... गठबंधन नहीं किया जाएगा"? – celion

+0

यह मुझे मिलता है। त्रुटि C2719: 'अज्ञात-पैरामीटर': __declspec (align ('16 ') के साथ औपचारिक पैरामीटर – watson1180

+0

संरेखित नहीं किया जाएगा x64 में, फ़ंक्शन तर्क 16-बाइट संरेखण का समर्थन करते हैं, इसलिए यह समस्या दूर हो जाती है। मुझे पता है कि आपकी तत्काल समस्या हल नहीं होती है, लेकिन हे, यह कुछ भी नहीं है। ;) – jalf

उत्तर

2

मुझे लगता है कि सामान्य रूप में यह करने के लिए केवल सुरक्षित तरीका संदर्भ द्वारा पारित करने के लिए है नहीं मिला। कुछ प्लेटफ़ॉर्म (उदा। Xbox 360) रजिस्टरों में वेक्टर तर्क पास करने का समर्थन करते हैं, लेकिन मुझे नहीं लगता कि यह x86 पर संभव है।

std::vector मामले के लिए, आपको यह सुनिश्चित करना होगा कि आवंटित स्मृति 16 बाइट्स से गठबंधन हो; अन्यथा जब आप unaligned वैक्टर पर अधिकतर संचालन करने का प्रयास करते हैं तो आपको क्रैश हो जाएगा।

यदि आप एकाधिक प्लेटफार्मों का समर्थन कर रहे हैं, तो एक सुरक्षित योजना typedef उदा।

typedef const MyVector& MyVectorParameter; 

फिर आप वेक्टर पास-बाय-वैल्यू का समर्थन करने वाले प्लेटफॉर्म पर टाइपपीफ को बदल सकते हैं।

+0

std :: vector <__m128> के साथ आवंटक सहायता को प्रतिस्थापित करना, लेकिन std :: vector अभी भी संकलित नहीं करता है। – watson1180

+0

क्या आपने 'sizeof (ए)' की जांच की थी? यदि यह 16 बाइट्स का बहुमत नहीं है, तो वेक्टर द्वारा आवंटित सरणी-संग्रहण के बाद के तत्वों को गठबंधन नहीं किया जाएगा, भले ही भंडारण की शुरुआत गठबंधन हो। –

+0

ए के प्लेटफॉर्म आकार पर 32 बाइट्स है।गलत संरेखण रनटाइम क्रैश का कारण बनता है, लेकिन वेक्टर आवंटक के बावजूद संकलित नहीं होगा। – watson1180

1

अक्सर उपयोग किए जाने वाले आकार() फ़ंक्शन सभी संरेखण का कारण बन रहा है और शायद आप __m128 के लिए वेक्टर टेम्पलेट को विशेषज्ञ बनाने का प्रयास कर सकते हैं?