C मैक्रो की परिभाषा बड़े एंडियन या छोटे एंडियन मशीन को निर्धारित करने के लिए?


107

क्या मशीन की समाप्ति का निर्धारण करने के लिए एक पंक्ति मैक्रो परिभाषा है। मैं निम्नलिखित कोड का उपयोग कर रहा हूं, लेकिन इसे मैक्रो में परिवर्तित करना बहुत लंबा होगा।

unsigned char test_endian( void )
{
    int test_var = 1;
    unsigned char *test_endian = (unsigned char*)&test_var;

    return (test_endian[0] == 0);
}

2
एक ही कोड को एक मैक्रो में शामिल क्यों नहीं किया जाता है?
शार्प्यूट

4
आप अकेले C प्रीप्रोसेसर के साथ धीरज का निर्धारण नहीं कर सकते। आप अपने अंतिम परीक्षण के 0बजाय भी चाहते हैं NULL, और test_endianवस्तुओं में से एक को कुछ और :-) में बदल सकते हैं।
आलोक सिंघल

2
इसके अलावा मैक्रो क्यों आवश्यक है? इनलाइन फ़ंक्शन समान होगा और बहुत सुरक्षित है।
शार्प्यूट

13
@ सहारा, एक मैक्रो अपील कर रहा है क्योंकि इसके मूल्य को संकलन समय पर जाना जा सकता है, जिसका अर्थ है कि आप टेम्पलेट तात्कालिकता को नियंत्रित करने के लिए अपने प्लेटफ़ॉर्म की समाप्ति का उपयोग कर सकते हैं, उदाहरण के लिए, या शायद एक #ifनिर्देश के साथ कोड के विभिन्न ब्लॉकों का भी चयन करें ।
रोब कैनेडी

3
यह सच है, लेकिन अक्षम है। यदि मेरे पास थोड़ा-सा एंडियन सीपीयू है, और मैं वायर या फाइल में थोड़ा-सा एंडियन डेटा लिख ​​रहा हूं, तो मैं बहुत ज्यादा नहीं बल्कि डेटा को अनपैक करने और दोबारा इस्तेमाल करने से बचूंगा। मैं जीने के लिए वीडियो ड्राइवरों को लिखता था। यह बहुत महत्वपूर्ण है जब किसी वीडियो कार्ड पर पिक्सेल लिखते हुए आप हर जगह का अनुकूलन कर सकते हैं।
एडवर्ड फॉक

जवाबों:


102

कोड को मनमाने ढंग से बाइट के आदेशों का समर्थन करने के लिए, एक फाइल में डालने के लिए तैयार order32.h:

#ifndef ORDER32_H
#define ORDER32_H

#include <limits.h>
#include <stdint.h>

#if CHAR_BIT != 8
#error "unsupported char size"
#endif

enum
{
    O32_LITTLE_ENDIAN = 0x03020100ul,
    O32_BIG_ENDIAN = 0x00010203ul,
    O32_PDP_ENDIAN = 0x01000302ul,      /* DEC PDP-11 (aka ENDIAN_LITTLE_WORD) */
    O32_HONEYWELL_ENDIAN = 0x02030001ul /* Honeywell 316 (aka ENDIAN_BIG_WORD) */
};

static const union { unsigned char bytes[4]; uint32_t value; } o32_host_order =
    { { 0, 1, 2, 3 } };

#define O32_HOST_ORDER (o32_host_order.value)

#endif

आप के माध्यम से थोड़ा एंडियन सिस्टम के लिए जाँच करेगा

O32_HOST_ORDER == O32_LITTLE_ENDIAN

11
यह आपको एंडियन-नेस को रनटाइम तक तय नहीं करने देता । निम्नलिखित संकलन करने में विफल रहता है क्योंकि / **LittleEndian :: परिणाम -> 0 या 1 * / संरचना isLittleEndian {enum isLittleEndianResult {परिणाम = (O32_HOST_ORDER == O32_LITTLE_INIAN)}; };
user48956

3
क्या रनटाइम तक परिणाम प्राप्त करना असंभव है?
k06a 12

8
क्यों char? uint8_tयदि इस प्रकार उपलब्ध नहीं है (जो द्वारा जाँच की जा सकती है #if UINT8_MAX) बेहतर उपयोग और असफल । ध्यान दें कि CHAR_BITसे स्वतंत्र है uint8_t
एंड्रियास स्पिंडलर

2
यह c ++ में UB है: stackoverflow.com/questions/11373203/…
Lyberta

3
मुझे मिश्रण में एक और टॉस दें, पूर्णता के लिए:O32_HONEYWELL_ENDIAN = 0x02030001ul /* Honeywell 316 */
एडवर्ड फॉक

49

यदि आपके पास एक संकलक है जो C99 मिश्रित शाब्दिक का समर्थन करता है:

#define IS_BIG_ENDIAN (!*(unsigned char *)&(uint16_t){1})

या:

#define IS_BIG_ENDIAN (!(union { uint16_t u16; unsigned char c; }){ .u16 = 1 }.c)

सामान्य तौर पर, आपको कोड लिखने की कोशिश करनी चाहिए जो होस्ट प्लेटफ़ॉर्म की समाप्ति पर निर्भर नहीं करता है।


होस्ट-एंडियननेस-स्वतंत्र कार्यान्वयन का उदाहरण ntohl():

uint32_t ntohl(uint32_t n)
{
    unsigned char *np = (unsigned char *)&n;

    return ((uint32_t)np[0] << 24) |
        ((uint32_t)np[1] << 16) |
        ((uint32_t)np[2] << 8) |
        (uint32_t)np[3];
}

3
"आपको कोड लिखने की कोशिश करनी चाहिए जो होस्ट प्लेटफ़ॉर्म की समाप्ति पर निर्भर नहीं करता है"। दुर्भाग्य से मेरी दलील, "मुझे पता है कि हम एक POSIX संगतता परत लिख रहे हैं, लेकिन मैं ntoh को लागू नहीं करना चाहता, क्योंकि यह होस्ट प्लेटफ़ॉर्म की समाप्ति पर निर्भर करता है" हमेशा बहरे कानों पर गिरता था ;-)। ग्राफिक्स प्रारूप हैंडलिंग और रूपांतरण कोड मैंने देखा है अन्य मुख्य उम्मीदवार है - आप हर समय नेटल कॉलिंग से सब कुछ आधार नहीं करना चाहते हैं।
स्टीव जेसोप

5
आप ntohlएक ऐसे तरीके से लागू कर सकते हैं जो मेजबान प्लेटफ़ॉर्म की समाप्ति पर निर्भर नहीं करता है।
कैफे

1
@caf होस्ट-एंडियननेस-इंडिपेंडेंट तरीके से ntohl कैसे लिखेंगे?
हैदरी उउउर कोल्टुक

3
@AliVeli: मैंने उत्तर में एक उदाहरण कार्यान्वयन जोड़ा है।
कैफे

6
मुझे रिकॉर्ड के लिए भी जोड़ना चाहिए, "" (* (uint16_t *) "\ 0 \ xff" <0x100) "एक स्थिर में संकलित नहीं करेगा, चाहे मैं कितना भी अनुकूलन करूं, कम से कम gcc 4.5.2 के साथ। यह हमेशा निष्पादन योग्य कोड बनाता है।
एडवर्ड फॉक

43

कोई मानक नहीं है, लेकिन कई प्रणालियों पर <endian.h>आपको देखने के लिए कुछ परिभाषित करेगा।


30
के साथ #if __BYTE_ORDER == __LITTLE_ENDIANऔर धीरज का परीक्षण करें #elif __BYTE_ORDER == __BIG_ENDIAN। और एक #errorबीहड़ उत्पन्न करते हैं।
1

6
<endian.h>विंडोज पर उपलब्ध नहीं है
rustyx

2
एंड्रॉइड और क्रोमियम परियोजनाएं endian.hतब तक उपयोग करती हैं जब तक कि उन्हें परिभाषित __APPLE__या _WIN32परिभाषित नहीं किया जाता है।
patryk.beza

1
OpenBSD 6.3 में, <endian.h> नाम से पहले बिना अंडरस्कोर वाले #if BYTE_ORDER == LITTLE_ENDIAN(या BIG_ENDIAN) प्रदान करता है । _BYTE_ORDERकेवल सिस्टम हेडर के लिए है। __BYTE_ORDERअस्तित्व में नहीं है।
जॉर्ज कोहलर

@ To1ne मुझे संदेह है कि एंडियनस विंडोज के लिए प्रासंगिक है, क्योंकि विंडोज (कम से कम वर्तमान में) केवल x86 और एआरएम मशीनों पर चलता है। x86 हमेशा LE और ARM को आर्किटेक्चर का उपयोग करने के लिए कॉन्फ़िगर किया जा रहा है।
सिमोन

27

रन टाइम पर एंडियननेस का पता लगाने के लिए, आपको मेमोरी को रेफर करने में सक्षम होना चाहिए। यदि आप मानक C से चिपके रहते हैं, तो स्मृति में परिवर्तनशील घोषित करने के लिए एक कथन की आवश्यकता होती है, लेकिन मान लौटाने के लिए एक अभिव्यक्ति की आवश्यकता होती है। मैं नहीं जानता कि यह कैसे करना है एक ही मैक्रो में - यही कारण है कि जीसीसी एक्सटेंशन है :-)

यदि आप के पास .h फ़ाइल रखने के लिए तैयार हैं, तो आप परिभाषित कर सकते हैं

static uint32_t endianness = 0xdeadbeef; 
enum endianness { BIG, LITTLE };

#define ENDIANNESS ( *(const char *)&endianness == 0xef ? LITTLE \
                   : *(const char *)&endianness == 0xde ? BIG \
                   : assert(0))

और फिर आप ENDIANNESSमैक्रो का उपयोग अपनी इच्छानुसार कर सकते हैं ।


6
मुझे यह पसंद है क्योंकि यह छोटे और बड़े के अलावा अन्यमन्यता के अस्तित्व को स्वीकार करता है।
आलोक सिंघल

6
जिसके बारे में बोलते हुए, यह मैक्रो INT_ENDIANNESS, या यहां तक ​​कि UINT32_T_ENDIANNESS को कॉल करने के लायक हो सकता है, क्योंकि यह केवल एक प्रकार के भंडारण प्रतिनिधित्व का परीक्षण करता है। वहाँ एक एआरएम एबीआई है जहां अभिन्न प्रकार छोटे-अंतियन हैं, लेकिन युगल मध्य-अंतियन हैं (प्रत्येक शब्द थोड़ा-सा-अंतियन है, लेकिन इसमें साइन बिट वाला शब्द दूसरे शब्द से पहले आता है)। कि एक या एक दिन के लिए संकलक टीम के बीच कुछ उत्तेजना पैदा हुई, मैं आपको बता सकता हूं।
स्टीव जेसोप

19

यदि आप केवल प्रीप्रोसेसर पर निर्भर रहना चाहते हैं, तो आपको पूर्वनिर्धारित प्रतीकों की सूची का पता लगाना होगा। प्रीप्रोसेसर अंकगणित में पते की कोई अवधारणा नहीं है।

मैक पर जीसीसी परिभाषित करता है __LITTLE_ENDIAN__या__BIG_ENDIAN__

$ gcc -E -dM - < /dev/null |grep ENDIAN
#define __LITTLE_ENDIAN__ 1

फिर, आप प्लेटफॉर्म डिटेक्शन #ifdef _WIN32आदि के आधार पर अधिक प्रीप्रोसेसर सशर्त निर्देश जोड़ सकते हैं ।


6
लिनक्स पर जीसीसी 4.1.2 उन मैक्रोज़ को परिभाषित करने के लिए प्रकट नहीं होता है, हालांकि जीसीसी 4.0.1 और 4.2.1 उन्हें मैकिंटोश पर परिभाषित करते हैं। तो यह क्रॉस-प्लेटफॉर्म विकास के लिए एक विश्वसनीय तरीका नहीं है, तब भी जब आपको यह निर्धारित करने की अनुमति दी जाती है कि किस कंपाइलर का उपयोग करना है।
रोब कैनेडी

1
ओह, यह इसलिए है क्योंकि यह केवल मैक पर जीसीसी द्वारा परिभाषित किया गया है।
ग्रेगोरी पकोस

नोट: मेरा जीसीसी (मैक पर) परिभाषित करता है #define __BIG_ENDIAN__ 1और #define _BIG_ENDIAN 1

Clang 5.0.1 OpenBSD / amd64 के लिए है #define __LITTLE_ENDIAN__ 1। यह मैक्रो एक क्लैंग फीचर लगता है, न कि जीसीसी फीचर। gccकुछ Macs में आदेश जीसीसी, यह बजना नहीं है।
जॉर्ज कोहेलर

मैक पर जीसीसी 4.2.1 तब जीसीसी वापस आ गया था
ग्रेगरी पॉक्सोज

15

मेरा मानना ​​है कि यह वही है जो पूछा गया था। मैंने केवल msvc के तहत थोड़ा एंडियन मशीन पर यह परीक्षण किया। एक बड़े एंडियन मशीन पर किसी को प्लिस की पुष्टि होती है।

    #define LITTLE_ENDIAN 0x41424344UL 
    #define BIG_ENDIAN    0x44434241UL
    #define PDP_ENDIAN    0x42414443UL
    #define ENDIAN_ORDER  ('ABCD') 

    #if ENDIAN_ORDER==LITTLE_ENDIAN
        #error "machine is little endian"
    #elif ENDIAN_ORDER==BIG_ENDIAN
        #error "machine is big endian"
    #elif ENDIAN_ORDER==PDP_ENDIAN
        #error "jeez, machine is PDP!"
    #else
        #error "What kind of hardware is this?!"
    #endif

एक साइड नोट (संकलक विशिष्ट) के रूप में, एक आक्रामक संकलक के साथ आप "मृत कोड उन्मूलन" अनुकूलन का उपयोग कर सकते हैं #ifताकि संकलन समय के समान प्रभाव प्राप्त हो सके:

    unsigned yourOwnEndianSpecific_htonl(unsigned n)
    {
        static unsigned long signature= 0x01020304UL; 
        if (1 == (unsigned char&)signature) // big endian
            return n;
        if (2 == (unsigned char&)signature) // the PDP style
        {
            n = ((n << 8) & 0xFF00FF00UL) | ((n>>8) & 0x00FF00FFUL);
            return n;
        }
        if (4 == (unsigned char&)signature) // little endian
        {
            n = (n << 16) | (n >> 16);
            n = ((n << 8) & 0xFF00FF00UL) | ((n>>8) & 0x00FF00FFUL);
            return n;
        }
        // only weird machines get here
        return n; // ?
    }

उपरोक्त इस तथ्य पर निर्भर करता है कि संकलक लगातार समय पर मूल्यों को पहचानता है, पूरी तरह से कोड को हटाता है और कोड को सबसे खराब स्थिति के साथ if (false) { ... }बदल देता है: कंपाइलर अनुकूलन नहीं करता है, फिर भी आपको सही कोड मिलता है लेकिन थोड़ा धीमा।if (true) { foo(); }foo();


मुझे यह तरीका पसंद है, लेकिन अगर मैं गलत हूं तो मुझे सुधारें: यह तभी काम करता है जब आप उस मशीन पर संकलन कर रहे हों जिसके लिए आप निर्माण कर रहे हैं, सही है?
leetNightshade

3
मल्टी-कैरेक्टर कैरेक्टर कॉन्स्टेंट के कारण gcc भी एरर देता है। इस प्रकार, पोर्टेबल नहीं।
एडवर्ड फॉक

2
संकलक आपको क्या लिखने दे रहा है 'ABCD'?
रयान हेनिंग

2
कई कंपाइलर्स मल्टीबीट कैरेक्टर कॉन्स्टेंट को रिलैक्स कंप्लायंस मोड्स में अनुमति देंगे, लेकिन clang -Wpedantic -Werror -Wall -ansi foo.cइसके साथ टॉप पार्ट को रन करेंगे और यह एरर करेगा। (बजना और यह विशेष रूप से: -Wfour-char-constants -Werror)

@ एडवर्ड फालक यह कोड में एक बहु-चरित्र स्थिर रखने के लिए एक त्रुटि नहीं है । यह कार्यान्वयन-परिभाषित व्यवहार C11 6.4.4.4 है। 10. gcc और अन्य सेटिंग्स के आधार पर चेतावनी / त्रुटि नहीं कर सकते हैं, लेकिन यह C त्रुटि नहीं है। यह निश्चित रूप से बहु-चरित्र चरित्र स्थिरांक का उपयोग करने के लिए लोकप्रिय नहीं है।
chux -

10

यदि आप एक संकलन समय परीक्षण की तलाश कर रहे हैं और आप जीसीसी का उपयोग कर रहे हैं, तो आप कर सकते हैं:

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__

अधिक जानकारी के लिए gcc प्रलेखन देखें ।


3
यह निश्चित रूप से gcc का उपयोग करने वाले किसी भी व्यक्ति के लिए सबसे अच्छा उत्तर है
rtpax

2
__BYTE_ORDER__जीसीसी 4.6 के बाद से उपलब्ध है
बेनोइट ब्लैंचॉन

8

आप वास्तव में एक यौगिक शाब्दिक (C99) का उपयोग करके एक अस्थायी वस्तु की स्मृति तक पहुँच सकते हैं :

#define IS_LITTLE_ENDIAN (1 == *(unsigned char *)&(const int){1})

संकलन समय पर कौन सा GCC मूल्यांकन करेगा।


मुझें यह पसंद है। क्या यह जानने का कोई पोर्टेबल, संकलन-समय है कि आप C99 के तहत संकलन कर रहे हैं?
एडवर्ड फॉक

1
ओह, और क्या होगा अगर यह जीसीसी नहीं है?
एडवर्ड फॉक

1
@EdwardFalk हाँ। #if __STDC_VERSION__ >= 199901L
जेन्स

7

'सी नेटवर्क लाइब्रेरी' एंडियननेस को संभालने के लिए फ़ंक्शन प्रदान करता है। नामली htons (), htonl (), ntohs () और ntohl () ... जहां n "नेटवर्क" (यानी। बड़ा-एंडियन) है और h "होस्ट" (यानी।) मशीन के एंडियननेस चल रहा है। कोड)।

ये स्पष्ट 'कार्य' (सामान्यतः) मैक्रोज़ के रूप में परिभाषित किए गए हैं [देखें <netinet / in.h>], इसलिए उनका उपयोग करने के लिए कोई रनटाइम ओवरहेड नहीं है।

निम्नलिखित मैक्रों एंडियन'स का मूल्यांकन करने के लिए इन 'कार्यों' का उपयोग करते हैं।

#include <arpa/inet.h>
#define  IS_BIG_ENDIAN     (1 == htons(1))
#define  IS_LITTLE_ENDIAN  (!IS_BIG_ENDIAN)

के अतिरिक्त:

किसी सिस्टम की एंडियननेस जानने के लिए मुझे केवल एक ही समय की आवश्यकता होती है, जब मैं एक वेरिएबल [एक फाइल / अन्य के लिए] लिखता हूं, जो अज्ञात एंडियननेस के दूसरे सिस्टम द्वारा रीड-इन किया जा सकता है (क्रॉस-प्लेटफॉर्म कॉम्पेटिबिलिटी के लिए) ) ... इन जैसे मामलों में, आप सीधे एंडियन कार्यों का उपयोग करना पसंद कर सकते हैं:

#include <arpa/inet.h>

#define JPEG_MAGIC  (('J'<<24) | ('F'<<16) | ('I'<<8) | 'F')

// Result will be in 'host' byte-order
unsigned long  jpeg_magic = JPEG_MAGIC;

// Result will be in 'network' byte-order (IE. Big-Endian/Human-Readable)
unsigned long  jpeg_magic = htonl(JPEG_MAGIC);

यह वास्तव में उस सवाल का जवाब नहीं देता है जो धीरज का निर्धारण करने के लिए एक त्वरित तरीके की तलाश कर रहा था।
ओरेन

@ ऑरेन: आपकी मान्य आलोचना के संबंध में, मैंने विस्तृत विवरण प्रस्तुत किया है जो मूल प्रश्न को अधिक सीधे संबोधित करता है।
ब्लूशिप

6

मैक्रो के बजाय इनलाइन फ़ंक्शन का उपयोग करें। इसके अलावा, आपको मेमोरी में कुछ स्टोर करने की आवश्यकता है जो कि मैक्रो का एक नहीं-अच्छा-अच्छा साइड इफेक्ट है।

आप इसे स्थैतिक या वैश्विक वैरिएबल का उपयोग करते हुए इसे लघु मैक्रो में बदल सकते हैं:

static int s_endianess = 0;
#define ENDIANESS() ((s_endianess = 1), (*(unsigned char*) &s_endianess) == 0)

मुझे लगता है कि यह सबसे अच्छा है क्योंकि यह सबसे सरल है। हालांकि यह मिश्रित एंडियन के खिलाफ परीक्षण नहीं करता है
हेरी उउर कोल्टुक

1
s_endianessशुरू करने के लिए 1 पर सेट क्यों नहीं है ?
स्क्वायररूटऑफट्वेंट्री

5

जब तक कोई पोर्टेबल #define या कुछ पर भरोसा करने के लिए नहीं है, तब तक प्लेटफॉर्म आपके 'होस्ट' एंडियन से परिवर्तित करने के लिए मानक कार्य प्रदान करते हैं।

आम तौर पर, आप भंडारण करते हैं - डिस्क, या नेटवर्क पर - 'नेटवर्क एंडियन' का उपयोग करते हुए, जो कि बीआईजी एंडियन है, और होस्ट एंडियन (जो x86 पर LITTLE एंडियन है) का उपयोग करके स्थानीय गणना करता है । आप उपयोग करते हैं htons()और ntohs()दोस्तों को दोनों के बीच कनवर्ट करने के लिए।


4
#include <stdint.h>
#define IS_LITTLE_ENDIAN (*(uint16_t*)"\0\1">>8)
#define IS_BIG_ENDIAN (*(uint16_t*)"\1\0">>8)

6
यह निष्पादन योग्य कोड भी बनाता है, स्थिर नहीं। आप "# IS IS_BIG_ENDIAN" नहीं कर सके
एडवर्ड फॉक

मुझे यह समाधान पसंद है क्योंकि यह सी / सी ++ मानकों पर अपरिभाषित व्यवहार पर भरोसा नहीं करता है, जहां तक ​​मैं समझता हूं। यह संकलित समय नहीं है, लेकिन इसके लिए एकमात्र मानक समाधान c ++ 20 std :: endian
ceztko

4

यह मत भूलो कि धीरज पूरी कहानी नहीं है - आकार char8 बिट्स (जैसे डीएसपी) नहीं हो सकता है, दो के पूरक निषेध की गारंटी नहीं है (जैसे क्रे), सख्त संरेखण की आवश्यकता हो सकती है (जैसे SPARC, एआरएम स्प्रिंग्स भी बीच में -अभिनय होने पर), आदि, आदि।

यह एक विशिष्ट सीपीयू वास्तुकला को लक्षित करने के लिए एक बेहतर विचार हो सकता है बजाय ।

उदाहरण के लिए:

#if defined(__i386__) || defined(_M_IX86) || defined(_M_IX64)
  #define USE_LITTLE_ENDIAN_IMPL
#endif

void my_func()
{
#ifdef USE_LITTLE_ENDIAN_IMPL
  // Intel x86-optimized, LE implementation
#else
  // slow but safe implementation
#endif
}

ध्यान दें कि यह समाधान भी अल्ट्रा-पोर्टेबल दुर्भाग्य से नहीं है, क्योंकि यह संकलक-विशिष्ट परिभाषाओं पर निर्भर करता है (कोई मानक नहीं है, लेकिन यहां ऐसी परिभाषाओं का एक अच्छा संकलन है)।



2

कृपया ध्यान दें कि यहां अधिकांश उत्तर पोर्टेबल नहीं हैं, क्योंकि कंपाइलर आज संकलन समय (अनुकूलन पर निर्भर करता है) में उन उत्तरों का मूल्यांकन करेंगे और एक विशिष्ट एंडियननेस के आधार पर एक विशिष्ट मान लौटाएंगे, जबकि वास्तविक मशीन एंडियननेस अलग हो सकती है। जिन मूल्यों पर एंडियननेस का परीक्षण किया गया है, वे सिस्टम मेमोरी तक कभी नहीं पहुंचेंगे, इसलिए वास्तविक निष्पादित कोड वास्तविक एंडियननेस की परवाह किए बिना एक ही परिणाम लौटाएगा।

उदाहरण के लिए , ARM Cortex-M3 में कार्यान्वित एंडियननेस एक स्थिति बिट AIRCR.ENDIANNESS में प्रदर्शित होगी और संकलनकर्ता संकलन समय में इस मूल्य को नहीं जान सकता है।

यहां दिए गए कुछ जवाबों के लिए संकलन आउटपुट:

इस उत्तर के लिए https://godbolt.org/z/GJGNE2 ,

https://godbolt.org/z/Yv-pyJ के लिए इस उत्तर के , और इसी तरह।

इसे हल करने के लिए आपको volatileक्वालीफायर का उपयोग करना होगा । Yogeesh H Tआज के वास्तविक जीवन के उपयोग के लिए इसका उत्तर सबसे नज़दीकी है, लेकिन चूंकि Christophअधिक व्यापक समाधान का सुझाव है, इसलिए उसके उत्तर के लिए थोड़ा सा सुधार उत्तर को पूर्ण कर देगा, बस volatileसंघ घोषणा में जोड़ें static const volatile union:।

यह मेमोरी से स्टोर करने और पढ़ने का आश्वासन देगा, जिसे एंडियननेस निर्धारित करने के लिए आवश्यक है।


2

यदि आप प्रीप्रोसेसर #defines को डंप करते हैं

gcc -dM -E - < /dev/null
g++ -dM -E -x c++ - < /dev/null

आप आमतौर पर सामान पा सकते हैं जो आपकी मदद करेगा। संकलन समय तर्क के साथ।

#define __LITTLE_ENDIAN__ 1
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__

हालांकि विभिन्न कंपाइलरों में अलग-अलग परिभाषित हो सकते हैं।


0

मेरा उत्तर उतना नहीं है, लेकिन यह पता लगाना बहुत आसान है कि क्या आपका सिस्टम थोड़ा एंडियन या बड़ा एंडियन है?

कोड:

#include<stdio.h>

int main()
{
  int a = 1;
  char *b;

  b = (char *)&a;
  if (*b)
    printf("Little Endian\n");
  else
    printf("Big Endian\n");
}

0

C कोड यह जांचने के लिए कि क्या कोई सिस्टम थोड़ा-सा एंडियन या बिग-इंडियन है।

int i = 7;
char* pc = (char*)(&i);
if (pc[0] == '\x7') // aliasing through char is ok
    puts("This system is little-endian");
else
    puts("This system is big-endian");

-3

मैक्रो एंडियन को खोजने के लिए

#define ENDIANNES() ((1 && 1 == 0) ? printf("Big-Endian"):printf("Little-Endian"))

या

#include <stdio.h>

#define ENDIAN() { \
volatile unsigned long ul = 1;\
volatile unsigned char *p;\
p = (volatile unsigned char *)&ul;\
if (*p == 1)\
puts("Little endian.");\
else if (*(p+(sizeof(unsigned long)-1)) == 1)\
puts("Big endian.");\
else puts("Unknown endian.");\
}

int main(void) 
{
       ENDIAN();
       return 0;
}

3
पहला मैक्रो गलत है और हमेशा "बिग-एंडियन" लौटाएगा। बिट शिफ्टिंग एंडियनस से प्रभावित नहीं होती है - एंडियननेस केवल मेमोरी में रीड और स्टोर को प्रभावित करता है।
गैसपड़प २ Gas ’
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.