मान लें मैं एक नमूना स्रोत फ़ाइल, test.c है, जो मुझे बहुत पसंद है संकलन रहा है:सी पर काबू पाने अलियासिंग प्रतिबंध (? यूनियनों)
$ जीसीसी -03 -Wall
परीक्षण। ग कुछ इस तरह दिखता ..
/// CMP128(x, y)
//
// arguments
// x - any pointer to an 128-bit int
// y - any pointer to an 128-bit int
//
// returns -1, 0, or 1 if x is less than, equal to, or greater than y
//
#define CMP128(x, y) // magic goes here
// example usages
uint8_t A[16];
uint16_t B[8];
uint32_t C[4];
uint64_t D[2];
struct in6_addr E;
uint8_t* F;
// use CMP128 on any combination of pointers to 128-bit ints, i.e.
CMP128(A, B);
CMP128(&C[0], &D[0]);
CMP128(&E, F);
// and so on
चलते भी कहते हैं कि मैं प्रतिबंध स्वीकार करते हैं कि अगर आप दो अतिव्यापी संकेत में गुजरती हैं, आप अपरिभाषित पुनः प्राप्त sults।
मैं कुछ इस तरह की कोशिश की है
#define CMP128(x, y) ({
uint64_t* a = (void*)x;
uint64_t* b = (void*)y;
// compare a[0] with b[0], a[1] with b[1]
})
(इन मैक्रो कल्पना ठीक से प्रत्येक पंक्ति के अंत में बैकस्लैश-एस्केप्ड नई-पंक्तियों के साथ स्वरूपित कर रहे हैं) लेकिन जब मैं भिन्नता मैक्रो में (एक [ 0] < बी [0]) मुझे जीसीसी
से त्रुटियों में "ड्रेफ्रेंसिंग ब्रेक सख्त-एलियासिंग नियम" त्रुटियां मिलती हैं, मैंने सोचा था कि आपको दो अलग-अलग तरीकों से स्मृति में एक ही स्थान को उचित रूप से संदर्भित करने के लिए यूनियनों का उपयोग करना था, इसलिए अगले मैंने कुछ कोशिश की जैसे
#define CMP128(x, y) ({
union {
typeof(x) a;
typeof(y) b;
uint64_t* c;
} d = { .a = (x) }
, e = { .b = (y) };
// compare d.c[0] with e.c[0], etc
})
कि सिवाय मैं सख्त अलियासिंग नियमों के बारे में संकलक से ठीक उसी त्रुटियों मिलता है।
तो: क्या सख्त-एलियासिंग तोड़ने के बिना ऐसा करने का कोई तरीका है, वास्तव में की तुलना स्मृति? उपयोग memcmp यह करने के लिए:
संपादित करें (may_alias does not को गिनती, यह सिर्फ आप सख्त अलियासिंग नियम बायपास करने के लिए अनुमति देता है)। मैं अलियासिंग नियमों पर पकड़ा गया और इसके बारे में नहीं सोचा।
मानक-अनुरूप तरीके से यूनियनों का उपयोग करने के लिए, आपको केवल उस सदस्य से पढ़ने की अनुमति है जिसे आपने पिछली बार लिखा था। –
@ केरेक: सच नहीं - सी 99 यूनियनों के माध्यम से टाइप-पनिंग की अनुमति देता है, एक फुटनोट जो उल्लेख करता है कि यह स्पष्ट रूप से टीसी 3 के साथ जोड़ा गया था; हालांकि, टोड का कोड अभी भी गलत है ... – Christoph
@ क्रिस्टोफ: सी 1 एक्स भी बेहतर है, परिशिष्ट जे (यूबी) तय किया गया है, अंतिम लिखित सदस्य से संबंधित बाइट पढ़ने की अनुमति देने के लिए (जो स्पष्ट रूप से सी 99 में उद्देश्य था, लेकिन स्पष्ट रूप से परिशिष्ट जे को तब अनदेखा किया गया था)। – ninjalj