সি ম্যাক্রো সংজ্ঞা বড় এন্ডিয়ান বা সামান্য এন্ডিয়ান মেশিন নির্ধারণ করবেন?


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
আপনি একমাত্র সি প্রিপ্রোসেসরের সাহায্যে বহনযোগ্যতা নির্ধারণ করতে পারবেন না। আপনি নিজের চূড়ান্ত পরীক্ষার 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 * / স্ট্রাক্টস লিটেল ইন্দিয়ান {এনাম isLittleEndianResult {ফলাফল = (O32_HOST_ordER == O32_LITTLE_ENDIAN)}; };
ব্যবহারকারী 48956

3
রানটাইম না হওয়া পর্যন্ত ফল পাওয়া কি অযোগ্য?
k06a

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
"আপনার কোডটি লেখার চেষ্টা করা উচিত যা হোস্ট প্ল্যাটফর্মের শেষের উপর নির্ভর করে না"। দুর্ভাগ্যক্রমে আমার আবেদন, "আমি জানি আমরা একটি পসিক্স সামঞ্জস্যতা স্তরটি লিখছি, তবে আমি ntoh প্রয়োগ করতে চাই না, কারণ এটি হোস্ট প্ল্যাটফর্মের অন্তর্নিহিততার উপর নির্ভর করে" সর্বদা বধির কানে পড়ে ;-)। গ্রাফিক্স ফর্ম্যাট হ্যান্ডলিং এবং রূপান্তর কোডটি আমি দেখেছি এমন অন্যান্য প্রধান প্রার্থী - আপনি সর্বদা ntohl কলিং থেকে সমস্ত কিছু বেস করতে চান না।
স্টিভ জেসোপ

5
আপনি ntohlএমন কোনও উপায়ে বাস্তবায়ন করতে পারেন যা হোস্ট প্ল্যাটফর্মের শেষের উপর নির্ভর করে না।
ক্যাফে

1
@ কেএফ আপনি কীভাবে একটি হোস্ট-এন্ডিয়ানেশন-স্বাধীন পদ্ধতিতে এনটিওএল লিখবেন?
হ্যারি উউর কলটুক

3
@ অলিভেলি: আমি উত্তরে একটি উদাহরণ প্রয়োগ করেছি।
ক্যাফে

6
আমারও রেকর্ডের জন্য যোগ করা উচিত, যে "(* (uint16_t *)" "\ 0 \ xff" <0x100) "কমপক্ষে জিসিসি 4.5.2 সহ আমি যতই অপ্টিমাইজ করি না কেন, একটি ধ্রুবক তৈরি করতে চাই না। এটি সর্বদা সম্পাদনযোগ্য কোড তৈরি করে।
এডওয়ার্ড ফাল

43

কোনও মান নেই, তবে অনেকগুলি সিস্টেমে <endian.h>আপনাকে অনুসন্ধানের জন্য কিছু সংজ্ঞা প্রদান করবে।


30
#if __BYTE_ORDER == __LITTLE_ENDIANএবং এর সাথে শেষের পরীক্ষা করুন #elif __BYTE_ORDER == __BIG_ENDIAN। এবং #errorঅন্যভাবে উত্পন্ন ।
To1ne

6
<endian.h>উইন্ডোজ
rustyx

2
অ্যান্ড্রয়েড এবং ক্রোমিয়াম প্রকল্পগুলি সংজ্ঞায়িত বা সংজ্ঞায়িত endian.hনা করা ব্যবহার করে । __APPLE___WIN32
patryk.beza

1
ওপেনবিএসডি .3.৩ এ <endian.h> #if BYTE_ORDER == LITTLE_ENDIAN(বা BIG_ENDIAN) নামের আগে কোনও আন্ডারস্কোর সরবরাহ করে না। _BYTE_ORDERশুধুমাত্র সিস্টেম শিরোলেখের জন্য। __BYTE_ORDERএটির অস্তিত্ব নেই.
জর্জ কোহলার

@ টুয়েন আমি সন্দেহ করি যে উইন্ডোজ (অন্তত বর্তমানে) কেবলমাত্র x86 এবং এআরএম মেশিনে চলমান এন্ডিয়ানসনেস উইন্ডোজের জন্য প্রাসঙ্গিক। x86 সর্বদা এলই এবং আরআরএম উভয়ই কোনও স্থাপত্য ব্যবহারের জন্য কনফিগারযোগ্য।
সাইমনসি

27

রান সময় এন্ডিয়নেস সনাক্ত করতে, আপনাকে মেমরিটি উল্লেখ করতে সক্ষম হতে হবে। আপনি যদি স্ট্যান্ডার্ড সিটিতে লেগে থাকেন তবে মেমরিতে ভেরিয়েবল ঘোষণার জন্য একটি বিবৃতি প্রয়োজন, তবে একটি মান ফেরত দেওয়ার জন্য একটি অভিব্যক্তি প্রয়োজন। আমি জানি না কীভাবে এটি একটি একক ম্যাক্রোতে করতে হয় — এ কারণেই জিসিসির এক্সটেনশন রয়েছে :-)

আপনি যদি .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ইত্যাদির উপর ভিত্তি করে আরও প্রিপ্রসেসর শর্তাধীন নির্দেশিকা যুক্ত করতে পারেন etc.


6
লিনাক্সে জিসিসি ৪.১.২ এই ম্যাক্রোগুলি সংজ্ঞায়িত করে না, যদিও জিসিসি ৪.০.১ এবং ৪.২.১ এগুলি ম্যাকিনটোস-এ সংজ্ঞায়িত করে। সুতরাং ক্রস-প্ল্যাটফর্ম বিকাশের জন্য এটি একটি নির্ভরযোগ্য পদ্ধতি নয়, এমনকি যখন আপনাকে কোন সংকলকটি ব্যবহার করতে বাধ্য করা হয়।
রব কেনেডি

1
ওহ হ্যাঁ কারণ এটি কেবল ম্যাকের জিসিসি দ্বারা সংজ্ঞায়িত করা হয়েছে।
গ্রেগরি পাকোস্

দ্রষ্টব্য: আমার জিসিসি (ম্যাকে) সংজ্ঞা দেয় #define __BIG_ENDIAN__ 1এবং #define _BIG_ENDIAN 1

ওপেনবিএসডি / এএমডি 64 এর জন্য 5.0.1 ঝাঁকুনি রয়েছে #define __LITTLE_ENDIAN__ 1। এই ম্যাক্রোটি একটি জঞ্জি বৈশিষ্ট্য নয়, একটি ঝনঝন বৈশিষ্ট্য বলে মনে হচ্ছে। gccকিছু Macs- এর মধ্যে কমান্ড জিসিসি, এটা ঝনঝন নয়।
জর্জ কোহলার

ম্যাকের জিসিসি 4.2.1 তখন জিসিসি পিছনে ছিল
গ্রেগরি পাকোসজ

15

আমি বিশ্বাস করি এটিই যা চেয়েছিল। আমি এটি কেবল এমএসভিসি-এর অধীনে একটি অল্প ইন্ডিয়ান মেশিনে পরীক্ষা করেছি। কেউ একজন বড় এন্ডিয়ান মেশিনে নিশ্চিত হন।

    #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
বহু-চরিত্রের অক্ষরের কারণে জিসিসি ত্রুটিও ছুঁড়েছে। সুতরাং, বহনযোগ্য নয়।
এডওয়ার্ড ফ্যালক

2
কি সংকলক আপনাকে লিখতে দিচ্ছে 'ABCD'?
রায়ান হেইনিং

2
অনেক সংকলক রিল্যাক্স কমপ্লায়েন্স মোডে মাল্টিবাইট চরিত্রের ধ্রুবকগুলিকে মঞ্জুরি দেয় তবে এর উপরের অংশটি চালায় clang -Wpedantic -Werror -Wall -ansi foo.cএবং এটি ত্রুটিযুক্ত হবে। (ঝনঝন এবং এটি সুনির্দিষ্টভাবে -Wfour-char-constants -Werror:)

@ অ্যাডওয়ার্ড ফালক কোডটিতে বহু-চরিত্রের ধ্রুবক থাকা কোনও ত্রুটি নয় । এটি বাস্তবায়ন-সংজ্ঞায়িত আচরণ C11 6.4.4.4। 10. জিসিসি এবং অন্যান্য সেটিংসের উপর নির্ভর করে / ত্রুটি সতর্ক করতে / নাও দিতে পারে, তবে এটি কোনও সি ত্রুটি নয়। মাল্টি-ক্যারেক্টার ক্যারেন্টস্ট্যান্ট ব্যবহার করার জন্য এটি অবশ্যই জনপ্রিয় নয়।
chux -

10

আপনি যদি একটি সংকলন সময় পরীক্ষা খুঁজছেন এবং আপনি জিসিসি ব্যবহার করছেন, আপনি এটি করতে পারেন:

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__

আরও তথ্যের জন্য জিসিসি ডকুমেন্টেশন দেখুন ।


3
এটি অবশ্যই
সিসিসি

2
__BYTE_ORDER__জিসিসি 4.6
বেনোইট ব্লাঞ্চন

8

আপনি আসলে একটি যৌগিক আক্ষরিক (C99) ব্যবহার করে একটি অস্থায়ী বস্তুর স্মৃতি অ্যাক্সেস করতে পারেন :

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

কোন জিসিসি সংকলন সময়ে মূল্যায়ন করবে।


আমি এটা পছন্দ করি. আপনি সি 99 এর অধীনে সংকলন করছেন তা জানার জন্য কি কোনও বহনযোগ্য, সংকলন-সময় উপায় আছে?
এডওয়ার্ড ফালক

1
ওহ, এবং যদি এটি জিসিসি না হয়?
এডওয়ার্ড ফালক

1
@ অ্যাডওয়ার্ডফাল্ক হ্যাঁ #if __STDC_VERSION__ >= 199901L
জেনস

7

'সি নেটওয়ার্ক লাইব্রেরি' এন্ডিয়ান'নেস পরিচালনা করতে ফাংশন সরবরাহ করে। যেমন htons (), htonl (), ntohs () এবং ntohl () ... যেখানে n "নেটওয়ার্ক" (যেমন বিগ-এন্ডিয়ান) এবং h "হোস্ট" (যেমন। মেশিনটি চালাচ্ছে মেশিনের endian'ness) কোড)।

এই আপাত 'ফাংশনগুলি' (সাধারণত) ম্যাক্রো হিসাবে [সংজ্ঞায়িত <নেটনেট / ইন.এইচ>>] হিসাবে সংজ্ঞায়িত হয়, সুতরাং এগুলি ব্যবহারের জন্য কোনও রানটাইম ওভারহেড নেই।

নিম্নলিখিত ম্যাক্রোগুলি এন্ডিয়ান'সনেস মূল্যায়নের জন্য এই 'ফাংশন' ব্যবহার করে।

#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

যেখানে কোনও পোর্টেবল # ডেফাইন বা নির্ভর করার মতো কিছু নেই, প্ল্যাটফর্মগুলি আপনার 'হোস্ট' এন্ডিয়ান থেকে রূপান্তর করার জন্য স্ট্যান্ডার্ড ফাংশন সরবরাহ করে।

সাধারণত, আপনি 'নেটওয়ার্ক এন্ডিয়ান', যা বিআইজি এন্ডিয়ান এবং স্থানীয় গণনা হোস্ট এন্ডিয়ান ব্যবহার করে (যা x86 তে লিটল এন্ডিয়ান হয়) ব্যবহার করে আপনি স্টোরেজ করেন disk আপনি এই ব্যবহার 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
এটি এক্সিকিউটেবল কোডও জেনারেট করে, ধ্রুবক নয়। আপনি "#if IS_BIG_ENDIAN" করতে পারবেন না
এডওয়ার্ড

আমি এই সমাধানটি পছন্দ করি যেহেতু এটি সি / সি ++ মানের নির্ধারিত আচরণের উপর নির্ভর করে না, যতদূর আমি বুঝতে পারি। এটি সঙ্কলনের সময় নয় তবে এর একমাত্র মান সমাধানটি সি ++ ২০
তম স্ট্যান্ড

4

ভুলে যাবেন না যে পরিণতি পুরো গল্প নয় - আকারটি char8 বিট (উদাহরণস্বরূপ ডিএসপি'র) হতে পারে না, দু'টির পরিপূরক অবহেলা গ্যারান্টিযুক্ত নয় (যেমন ক্রে), কঠোর প্রান্তিককরণের প্রয়োজন হতে পারে (যেমন স্পার্ক, এছাড়াও এআরএম স্প্রিংস মাঝখানে ইন্ডিয়ান যখন আন-সাইন ইন ) ইত্যাদি ইত্যাদি etc.

পরিবর্তে একটি নির্দিষ্ট সিপিইউ আর্কিটেকচারকে লক্ষ্য করা আরও ভাল ধারণা হতে পারে ।

উদাহরণ স্বরূপ:

#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

দয়া করে মনোযোগ দিন যে এখানে বেশিরভাগ উত্তর পোর্টেবল নয়, কারণ সংকলকরা আজ এই সংকলনগুলির সময়গুলিতে উত্তরগুলি মূল্যায়ন করবে (অনুকূলিতকরণের উপর নির্ভর করে) এবং একটি নির্দিষ্ট সমাপ্তির উপর ভিত্তি করে একটি নির্দিষ্ট মান ফেরত দেবে, যখন প্রকৃত মেশিনের পরিণতি আলাদা হতে পারে। যে মানগুলির উপর শেষের পরীক্ষা করা হয়, তা কখনই সিস্টেমের মেমোরিতে পৌঁছায় না সুতরাং প্রকৃত সম্পাদিত কোডটি প্রকৃত পরিণতি নির্বিশেষে একই ফলাফল প্রদান করবে।

জন্য উদাহরণস্বরূপ , এআরএম বল্কল-M3 বাস্তবায়িত endianness একটি স্থিতি বিট AIRCR.ENDIANNESS প্রতিফলিত হবে এবং কম্পাইলার কম্পাইল সময় এই মান জানতে পারে না।

এখানে প্রস্তাবিত কিছু উত্তরের জন্য সংকলনের আউটপুট:

এই উত্তরের জন্য https://godbolt.org/z/GJGNE2 ,

https://godbolt.org/z/Yv-pyJ জন্য এই উত্তর, এবং তাই।

তার সমাধানের আপনি ব্যবহার করতে হবে volatileকোয়ালিফায়ার। Yogeesh H Tএর উত্তর আজকের বাস্তব জীবনে ব্যবহারের জন্য নিকটস্থ এক, কিন্তু যেহেতু Christophআরো ব্যাপক সমাধান প্রস্তাব দেওয়া, তার থেকে সামান্য ফিক্স উত্তর উত্তর সম্পূর্ণ, শুধু যোগ করতে হবে volatileইউনিয়ন ঘোষণা করুন: static const volatile union

এটি মেমরি থেকে স্টোরেজ এবং পড়ার নিশ্চয়তা দেবে যা অন্তরঙ্গতা নির্ধারণের জন্য প্রয়োজনীয়।


2

যদি আপনি প্রিপ্রসেসর # ডিফাইনগুলি ডাম্প করেন

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

কোনও সিস্টেম স্বল্প-এন্ডিয়ান বা বড়-ভারতীয় কিনা তা যাচাইয়ের জন্য সি কোড।

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
প্রথম ম্যাক্রোটি ভুল এবং সর্বদা "বিগ-এন্ডিয়ান" ফিরিয়ে দেবে। বিট শিফটিং এন্ডিনিয়েন্স দ্বারা প্রভাবিত হয় না - এন্ডিয়ানাটি কেবল মেমরির পাঠ এবং সঞ্চয়কে প্রভাবিত করে।
গ্যাসপার্ডপি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.