![]() |
|
#1
|
|||
|
|||
MACRO to detect big / little endianMay i know how can i write a marco to detect little endian format.
I know to do it using a function. But to simpify things, i would like to write a macro to do it. Thanks in advance. |
|||
|
#2
|
|||
|
|||
Re: MACRO to detect big / little endianQuote:
Quote:
I'm not sure how making it a macro will "simplify" it, but I am willing to learn. Regards, Dave |
|
#3
|
|||
|
|||
Re: MACRO to detect big / little endianQuote:
CPP / C++ / C Code:
I wanted make a macro because, before i want the decoder to know the endianess upon startup. If not i would need to check at every function that i invoke in the decoder. May some guys will have better ideas!!! Thanks in advance!! |
|
#4
|
||||
|
||||
Re: MACRO to detect big / little endianHello There.
To begin with let me direct you towards this post from this thread that it is not a good idea to use a macro when a function can do the same job. Thnks for the tip dave!!..I still remember it!! Well,moving on to ur function...I doubt the correctness of syntax of the following declaration. CPP / C++ / C Code:
Further you declare the function to return an unsigned char as its return value. However this comparison statement CPP / C++ / C Code:
I am running this on a sparc (ultra 10) so i know it is big endian. However does anybody know how C actually stores the data in memory. This should be machine dependent so the big endian machines store the higher order bytes in higher memory locations. But I wonder why you use the NULL character to test the endianness. Does C end all variables with the NULL character?I used to think this is only true incase of strings..i.e. char arrays as C would automatically append a NULL character after the last location. But for int?! On trying to compile this function into an executable called endianness and heres what i get from my compiler: Code:
CPP / C++ / C Code:
Well...u need to tell us how do YOU plan to test the endianness..have u come up with an idea. I'd be eager to know it. __________________
Hope to hear from you guys! -------------------------------------------------- Best Regards, Aijaz Baig. Last edited by aijazbaig1 : 25-Aug-2007 at 06:16.
Reason: adding some source code
|
|
#5
|
|||||||||||
|
|||||||||||
Re: MACRO to detect big / little endianQuote:
Quote:
Quote:
Quote:
An unsigned char is an integer data type. As an eight-bit quantity it can have any value from zero up to and including 255(decimal), so it certainly can take on values of zero and one. Quote:
Quote:
Well, that's the point of this little exercise: Create source code that can be compiled on any kind of platform and upon execution report on its endianness. Note, however that there are actually three kinds of endianness, not just two. See footnote. For the moment, let's just concentrate in big/little. Another question might be whether there is a way to create a program (with macros or whatever) for which the endianness could be determined at compile time. In other words, have the compiler spit out an error or some other kind of message that tests the endianness when compiling. I don't think it can be done portably (with standard C and the standard C library), and I would really (really) like to hear from anyone who knows how. Let's get back to the issue of detecting endianness at run time (with portable standard C and the standard C library). Quote:
Quote:
Quote:
Literal strings have a zero byte at the end (defined as a byte whose bits are all zero), and sometimes we speak of a null-terminated "C-style" string. But that's just English, not C. Lower-case "null" is not defined as an identifier in C or anywhere in the standard C library. Upper-case "NULL" is #defined as a pointer in <stdio.h> (or some file that gets included when you include <stdio.h>). Quote:
Here is the original program to which I have made minimal changes in order to get an absolutely clean compile according to the C89 standard: CPP / C++ / C Code:
My output: Code:
1. Give the function a meaningful name. Without the comment before the function definition, I would actually have to go through the logic to know what to expect out of the function. Now, comments are good, but I think that a proper selection of a name of the function to make it more-or-less self-documenting is even more important. So, since the function as written returns the C language equivalent of "true" for big-endian machines, I would probably name the function "is_big_endian()" or some such thing. 2. As we already agreed, creating a variable within the function that has the same name as the function could be confusing to us humans, I would give it another name. 3. Other minor changes are just a matter of habit. For one thing, unless I have a good reason to use something else, I just use ints for function return types, etc. No particular reason these days (but once upon a time with a Small C compiler for a Z-80, I found that the compiled code did more work dealing with chars than it did dealing with ints). CPP / C++ / C Code:
Note that there are slight variations on the way that the byte-order in memory can be tested. You can use something like CPP / C++ / C Code:
Quote:
Well, this is why it's hard to develop something like this without being able to test: I compiled and ran on my little-endian platform and here is the output: Code:
What happened? 1. This statement always returns a value of zero: CPP / C++ / C Code:
cptr is a pointer whose address is that of the variable test_var. Its value will never be NULL. (That's part of the C standard.) Maybe you meant: CPP / C++ / C Code:
One other little 'gotcha' is that the logic of your main program assumes that a return value of zero indicates a big_endian architecture. (That's why I suggested a more meaningful name for the function.) To get your function to work without changing your main program you could change the return statement to CPP / C++ / C Code:
Anyhow, with that single change, here's what I get: Code:
Thank you for posting and thank you for giving us a way to test on big-endian machines. (Note that users of older Macintosh computers---the one with a PowerPC CPU---can also test the big_endian functionality.) Regards, Dave Footnote: The good old PDP-11 (a 16-bit machine, and the first really successful minicomputer---the one that ate IBM's lunch back in the 1970's) had a different way of storing 32-bit integers:http://en.wikipedia.org/wiki/Endianness#Middle-endian. For the purposes of this post, I am ignoring that kind or architecture. |
|
#6
|
|||
|
|||
Re: MACRO to detect big / little endianQuote:
Quote:
Every serious C compiler has functions that are used in network applications to swap bytes (if necessary) as data are transferred into and out of memory to make sure the bytes in and out of network functions are in network order (big-endian). Note that these functions are not standard C (or C++) library functions as defined in the standard language specification. That's why different header files might be used for different compiler installations. The way it works is that somewhere in files that you include when you use the network functions, there is a machine-dependent #define (or some other mechanism) that works for that particular target architecture so that one version of each of the functions (actually, they might be macros) htonl(), htons(), ntohl() and ntohs() will swap bytes if the target architecture is little-endian but another version of each will leave them in the same order if the target is big-endian. Your application code always uses these functions when endianness is an issue. (Not for all data store and retrieve; just where you have to know that the object is big-endian.) The actual mechanism that determines which version of each function to use is hidden from the application programmer and is taken care of automatically by whatever configuration program was run when the compiler (and library) itself was installed for a particular target machine. (In other words, the compiler is set up to create code for whatever-endian machine is the target, and the functions are selected accordingly.) So: first of all do "man htonl" on your system and see if you get anything. It should show you what you would have to #include in order to use these functions. Windows programmers would #include winsock2.h>. On my Linux systems (and on Windows XP using cygwin/gcc), I #include <arpa/inet.h>, and that's what I show in the example below. Note that on a big-endian machine, htonx() and ntohx() don't actually have to do any work, and as a result, network I/O can actually be more efficient than on little-endian machines. (A fact that I wish the good designers at Intel would have taken into account when they designed the early 80xx chips. We might never have had to worry about endianness. Although, I will concede that, in the context of the early 1970's there might have been important reasons to commit to little-endian architecture. Motorola didn't think so.) Here's a little program that shows use of ntohl(), and the output shows what happens on a little-endian machine: CPP / C++ / C Code:
Output on my little-endian systems: Code:
If necessary, make whatever changes to include the proper header file to get it to compile. If your machine has a big-endian architecture, the bytes of x and the bytes of y should be the same: 0x12 0x34 0x56 0x78 Regards, Dave Last edited by davekw7x : 25-Aug-2007 at 12:11.
|
|
#7
|
|||
|
|||
Re: MACRO to detect big / little endianFirst of all, i would like to apologise for the type error and its
CPP / C++ / C Code:
For anness byte addressing, the test_endian is pointing to the first byte of the test_var which is 4 bytes (int). To test for endiannees, we need to check for the byte addressing. I intended to use a macro because, i wanted to determine the endianness of that platform, before i invoke my decoder. It would add to the decoding time IF i check for endianess in every byte operation. And of course, aijazbaig1 do u know whats endianness, the comments u gave dun really involved my query. Or rather maybe you are proving my errors. Anyway, i am not asking anyone to check for my errors, but to get the idea of what i am getting at. Once again, i would like to THANKS dave previous comments!!!!! |
|
#8
|
|||
|
|||
Re: MACRO to detect big / little endianTHANKS for all ur comments.
I am not working on programs for networking. The decoder works on an embedded system. Thus i would like to create a prtable decoder, if for future the decoder can be portable if i use a different chip. |
|
#9
|
|||
|
|||
Re: MACRO to detect big / little endianQuote:
I thought that the reason you needed a function or macro to determine system endianness was because getting 32-bit ints (or 16-bit ints) into and out of memory would require byte-swapping for little-endian machines but not for big-endian ones (or some such thing). Maybe I missed something. It wouldn't be the first time. See footnote. The suggestion was: If your system has htonl() and ntohl(), you can use them to write code that "automatically" decides whether byte-swapping is necessary and does whatever is necessary to get things from memory into a register in big-endian order so that the mathematical algorithm can work as expected. (All without having to change source code for different target architectures.) Since many libraries for embedded systems have htonl() and ntohl() (if you know where to look for them), I thought you might be interested in using them for your application, thus eliminating the need for your source code having to use the endianness-detecting function for each and every memory access. How about this: Give an example of where you would use your function (or macro) that influences the code in a way that depends on endianness of the target architecture. (If the endianness of the target doesn't affect the functionality, why would you want to test for it?) Regards, Dave We have already answered your first question as far as I know: I don't believe there is a portable way (using standard C language and libraries) to write a macro that, as an expression, evaluates to one value for a big-endian machine and another value for a little-endian machine. There are ways to write functions that correctly do this. Your function wasn't quite right, but I showed how to make it work, and I showed another, similar, way (there are, undoubtedly, other ways). Of course, another way would be to write the program so that it reads and writes bytes (i.e. chars) from and to memory instead of ints or other multi-byte quantities. Then endianness need never raise its ugly head. |
|
#10
|
|||
|
|||
Re: MACRO to detect big / little endianQuote:
For example. if i am decoding a music format, let say mp3, i need to do byte or bit accessing to get the data to be decoded. First of all the magic number for the header to determine what music format that file really is and perform the correct decoding method. I would look for the 2 functions that u recommanded form the mannual. THANKS AGAIN!!!!!! |
Recent GIDBlog
Install Adobe Flash - Without Administrator Rights by LocalTech
| Thread Tools | Search this Thread |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Help analyzing a linked list program | aijazbaig1 | C Programming Language | 22 | 01-Aug-2007 10:19 |
| how to detect mouse click in child window created by CHTMLEDITVIEW | terr | MS Visual C++ / MFC Forum | 0 | 08-Sep-2006 13:12 |
| difference between inline function and macro function | gemini_v440 | C++ Forum | 2 | 25-Mar-2006 20:36 |
| SWAP macro | alcoholic | C Programming Language | 4 | 15-Jan-2006 17:39 |
| Changing big/little endian | Dream86 | C++ Forum | 3 | 24-Jul-2005 20:13 |
Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The