473,395 Members | 1,578 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Big Endian - Little Endian

I have this program :

void main()
{
int i=1;
if((*(char*)&i)==1)
printf("The machine is little endian.");
else
printf("The machine is big endian.");
}

This program tells me if the machine uses big endian or little endian
format.
But I am not able to understand the working of this program. Can
someone please explain the working.

Thanks in advance.

Thanks,
Niranjan.
Aug 27 '08 #1
23 6995
On 27 Aug., 13:27, Niranjan <guruof...@gmail.comwrote:
I have this program :

void main()
{
* * int i=1;
* * if((*(char*)&i)==1)
* * * * *printf("The machine is little endian.");
* * else
* * * * *printf("The machine is big endian.");

}

This program tells me if the machine uses big endian or little endian
format.
But I am not able to understand the working of this program. Can
someone please explain the working.
int i=1;
This allocates space for an integer variable (usually 4 bytes) on the
stack (if your environment supports this concept :-). The bit pattern
for big-Endian systems will be 00000001_hex, and 01000000_hex for
little-Endian systems.
if((*(char*)&i)==1)
The pointer to i is casted to a pointer to char, leaving the pointer
value the same, but changing how the pointer is treated.
a a+1 a+2 a+3
----------------------------
| 01 | 00 | 00 | 00 | little endian
----------------------------
/\
/| \
|
pointer to i

a a+1 a+2 a+3
----------------------------
| 00 | 00 | 00 | 01 | big endian
----------------------------
/\
/| \
|
pointer to i

After the pointer has been casted to char*, it either points to a byte
that contains a one or a zero.
printf("The machine is little endian.");
else
printf("The machine is big endian.");
Regards,
Stuart
Aug 27 '08 #2
de*******@web.de wrote:
>int i=1;

This allocates space for an integer variable (usually 4 bytes) on the
stack (if your environment supports this concept :-).
Btw, does the standard guarantee that sizeof(int) sizeof(char)?
(OTOH, would endianess have any meaning in a system where they have
the same size?)

Moreover, does the standard guarantee that you can reinterpret-cast an
int* to a char*, and then dereference it safely?
Aug 27 '08 #3
On 27 Aug, 14:39, p...@informatimago.com (Pascal J. Bourguignon)
wrote:
Juha Nieminen <nos...@thanks.invalidwrites:
dertop...@web.de wrote:
<snip>
* Moreover, does the standard guarantee that you can reinterpret-castan
int* to a char*, and then dereference it safely?

AFAIK, no. *That is, there could be pad bits, or some other strange
mapping, so the test proposed wouldn't be right.

But in practice, on current machines, it works.
C (and by inheritance C++) guarentees that you can cast any
data pointer ("object" in C-speak) to a pointer to unsigned
char and be able to deref it. Hence you can always hex
dump the representation of an object. U chars *cannot*
have trap representations.

Also Big-endian and Little-endian doesn't exhaust the possibilities,
there are strange DEC-endians as well.
--
Nick Keighley
Aug 27 '08 #4
Nick Keighley wrote:
Also Big-endian and Little-endian doesn't exhaust the possibilities,
there are strange DEC-endians as well.
I've heard the DEC PDP-11 endianness called "PDP-endian", in which the
value 0x01234567 is stored as the bytes 0x45 0x67 0x01 0x02 at
increasing memory addresses.
--
Fran
Aug 27 '08 #5
Francis Litterio wrote:
Nick Keighley wrote:
>Also Big-endian and Little-endian doesn't exhaust the
possibilities, there are strange DEC-endians as well.

I've heard the DEC PDP-11 endianness called "PDP-endian", in which
the value 0x01234567 is stored as the bytes 0x45 0x67 0x01 0x02 at
increasing memory addresses.
Yes.

Some processors have run-time configured endianess, can be different
for different programs.

The DEC-endians also include the possibility of different endianness
for integers and floating point.

Bo Persson
Aug 27 '08 #6
All,

Thanks for your answers.
The only thing that I still am not clear is that why do we need to
type cast int* to char *.
What difference does it make?
We are not doing any pointer arithmatic or iterations here.
Then what is it that forces to explicit cast the pointer to (char
*)

Thanks,
Niranjan.
On Aug 27, 8:45*am, dertop...@web.de wrote:
On 27 Aug., 13:27, Niranjan <guruof...@gmail.comwrote:


I have this program :
void main()
{
* * int i=1;
* * if((*(char*)&i)==1)
* * * * *printf("The machine is little endian.");
* * else
* * * * *printf("The machine is big endian.");
}
This program tells me if the machine uses big endian or little endian
format.
But I am not able to understand the working of this program. Can
someone please explain the working.
int i=1;

This allocates space for an integer variable (usually 4 bytes) on the
stack (if your environment supports this concept :-). The bit pattern
for big-Endian systems will be 00000001_hex, and 01000000_hex for
little-Endian systems.
if((*(char*)&i)==1)

The pointer to i is casted to a pointer to char, leaving the pointer
value the same, but changing how the pointer is treated.
* * *a * * a+1 * *a+2 * * a+3
* *----------------------------
* *| 01 *| *00 *| *00 *| *00 *| * little endian
* *----------------------------
* * */\
* * /| \
* * *|
* * pointer to i

* * *a * * a+1 * *a+2 * * a+3
* *----------------------------
* *| 00 *| *00 *| *00 *| *01 *| * big endian
* *----------------------------
* * */\
* * /| \
* * *|
* * pointer to i

After the pointer has been casted to char*, it either points to a byte
that contains a one or a zero.
* printf("The machine is little endian.");
else
* printf("The machine is big endian.");

Regards,
Stuart- Hide quoted text -

- Show quoted text -

Aug 27 '08 #7
Niranjan wrote:
All,

Thanks for your answers.
The only thing that I still am not clear is that why do we need to
type cast int* to char *.
What difference does it make?
We are not doing any pointer arithmatic or iterations here.
Then what is it that forces to explicit cast the pointer to (char
*)
Type char has a double duty in C++, as it is both a character type and
the language's definition of a byte. So by casting an int pointer to a
char pointer, you access the first byte of the object.

Assuming, again, that an int is larger than a char, you access just
one part of the integer.

As you have seen in other posts, this doesn't cover all the corner
cases, but works well on popular desktop computers. On the other hand,
these computers are also known to be little endian, anyway.
Bo Persson
>
>On 27 Aug., 13:27, Niranjan <guruof...@gmail.comwrote:


>>I have this program :
>>void main()
{
int i=1;
if((*(char*)&i)==1)
printf("The machine is little endian.");
else
printf("The machine is big endian.");
>>}
>>This program tells me if the machine uses big endian or little
endian format.
But I am not able to understand the working of this program. Can
someone please explain the working.
int i=1;

Aug 27 '08 #8
On Wed, 27 Aug 2008 13:02:24 GMT, Juha Nieminen
<no****@thanks.invalidwrote in comp.lang.c++:
de*******@web.de wrote:
int i=1;
This allocates space for an integer variable (usually 4 bytes) on the
stack (if your environment supports this concept :-).

Btw, does the standard guarantee that sizeof(int) sizeof(char)?
(OTOH, would endianess have any meaning in a system where they have
the same size?)
Not only does the standard NOT guarantee this, there are
architectures, usually digital signal processors, where this is not
true. And there are C++ implementation for some of these
architectures these days. Not full hosted implementations, for sure,
and not even full free standing implementations, but usually fairly
well conforming to the (non-ISO) "Embedded C++" subset.

Endianness has no meaning on platforms like some 32-bit DSPs where all
integer types, char, short, int, and long, are all 32 bits and have
identical representation.

On the other hand, some DSPs have 16-bit char, short, and int, and
32-bit long. Endianness of a long has meaning. On the Texas
Instruments TMS320C28x family, for example, longs are little endian.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Aug 28 '08 #9
On 27 Aug., 13:27, Niranjan <guruof...@gmail.comwrote:
I have this program :
void main()
{
int i=1;
if((*(char*)&i)==1)
printf("The machine is little endian.");
else
printf("The machine is big endian.");
}
This program tells me if the machine uses big endian or little endian
format.
But I am not able to understand the working of this program. Can
someone please explain the working.
On 27 Aug., 19:37, Niranjan <guruof...@gmail.comwrote:
All,

Thanks for your answers.
The only thing that I still am not clear is that why do we need to
type cast int* to char *.
What difference does it make?
We are not doing any pointer arithmatic or iterations here.
Then what is it that forces to explicit cast the pointer to (char
*)

Thanks,
Niranjan.
The explicit cast is necessary to force the compiler to treat the
memory of the integer variable as if it was memory to hold a char
variable. Dereferencing the casted pointer will read only the byte at
location a, whereas dereferencing the original int pointer will read
the bytes at locations a to a + 3.

Regards,
Stuart
Aug 28 '08 #10
On Aug 27, 2:45 pm, dertop...@web.de wrote:
On 27 Aug., 13:27, Niranjan <guruof...@gmail.comwrote:
I have this program :
void main()
{
int i=1;
if((*(char*)&i)==1)
printf("The machine is little endian.");
else
printf("The machine is big endian.");
}
This program tells me if the machine uses big endian or
little endian format. But I am not able to understand the
working of this program. Can someone please explain the
working.
int i=1;
This allocates space for an integer variable (usually 4 bytes)
on the stack (if your environment supports this concept :-).
Often 4 bytes today, but I imagine that there are still a lot of
machines where it is 2 bytes. Values of 6 and 1 are also known,
and other values wouldn't surprise me either.
The bit pattern for big-Endian systems will be 00000001_hex,
and 01000000_hex for little-Endian systems.
The bit pattern is required by the standard to be 0x00000001
(supposing 32 bits). No other alternatives are allowed.
if((*(char*)&i)==1)
The pointer to i is casted to a pointer to char, leaving the pointer
value the same, but changing how the pointer is treated.
Again, on most machines. There are (or have been) machines
where the pointer value will change; there are (or have been)
machines where the two pointers will not even have the same
size.
a a+1 a+2 a+3
----------------------------
| 01 | 00 | 00 | 00 | little endian
----------------------------
/\
/| \
|
pointer to i
a a+1 a+2 a+3
----------------------------
| 00 | 00 | 00 | 01 | big endian
----------------------------
/\
/| \
|
pointer to i
After the pointer has been casted to char*, it either points
to a byte that contains a one or a zero.
That's generally true on most modern general purpose machines,
but you can't count on it.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 31 '08 #11
On Aug 27, 3:02 pm, Juha Nieminen <nos...@thanks.invalidwrote:
dertop...@web.de wrote:
int i=1;
This allocates space for an integer variable (usually 4 bytes) on the
stack (if your environment supports this concept :-).
Btw, does the standard guarantee that sizeof(int) sizeof(char)?
No.
(OTOH, would endianess have any meaning in a system where they have
the same size?)
Does it really have any meaning internally even when the sizes
are different?
Moreover, does the standard guarantee that you can reinterpret-cast an
int* to a char*, and then dereference it safely?
Yes, but the results are unspecified.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 31 '08 #12
James Kanze wrote:
> (OTOH, would endianess have any meaning in a system where they have
the same size?)

Does it really have any meaning internally even when the sizes
are different?
If you write some values to a file eg. with fwrite(), it can make a
difference.
Aug 31 '08 #13
On Aug 31, 2:38 pm, Juha Nieminen <nos...@thanks.invalidwrote:
James Kanze wrote:
(OTOH, would endianess have any meaning in a system where they have
the same size?)
Does it really have any meaning internally even when the sizes
are different?
If you write some values to a file eg. with fwrite(), it can
make a difference.
I'm afraid I don't understand. fwrite() really doesn't do
anything that ostream::write() doesn't; it just has an interface
which pretends to. If you have to reread the file at some
future date, possibly with a different program, or a new version
of the same program, then you have to write (and read) a
specified format. Neither fwrite() nor ostream::write() do
this; neither really make much sense unless the argument is a
preformatted buffer (except for the case where you are using the
file as extended memory within the program---frequent back in
the days of 8 or 16 bit processors, and a total memory of only
64 KB, but I can't imagine the need today, with 64 bits virtual
address space).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Aug 31 '08 #14
James Kanze wrote:
but I can't imagine the need today, with 64 bits virtual
address space).
Clearly you have never needed to read/write humongous amounts of data
as fast as possible.
Sep 1 '08 #15
On Sep 1, 4:54 pm, Juha Nieminen <nos...@thanks.invalidwrote:
James Kanze wrote:
but I can't imagine the need today, with 64 bits virtual
address space).
Clearly you have never needed to read/write humongous amounts
of data as fast as possible.
You'd be surprised:-).

In the good old days, when we had to fit the application into
64KB, just dumping the bits was a very efficient way to
implement overlays of data (and of code, for that matter, if the
system and the linker supported it). Today, however, the
address space of virtual memory is larger than the biggest disks
I can get my hands on, so the only reason I would explicitly
write to disk (as opposed to paging) is because I need to be
able to reread it later. Which means that it must have a
defined format, and just dumping the bits doesn't work.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 1 '08 #16
Juha Nieminen wrote:
James Kanze wrote:
>> (OTOH, would endianess have any meaning in a system where they have
the same size?)
Does it really have any meaning internally even when the sizes
are different?

If you write some values to a file eg. with fwrite(), it can make a
difference.
Not if you use an endian neutral file system.

--
Ian Collins.
Sep 1 '08 #17
On 1 Sep., 22:24, James Kanze <james.ka...@gmail.comwrote:
On Sep 1, 4:54 pm, Juha Nieminen <nos...@thanks.invalidwrote:
James Kanze wrote:
but I can't imagine the need today, with 64 bits virtual
address space).
Clearly you have never needed to read/write humongous amounts
of data as fast as possible.

You'd be surprised:-).

In the good old days, when we had to fit the application into
64KB, just dumping the bits was a very efficient way to
implement overlays of data (and of code, for that matter, if the
system and the linker supported it). *Today, however, the
address space of virtual memory is larger than the biggest disks
I can get my hands on, so the only reason I would explicitly
write to disk (as opposed to paging) is because I need to be
able to reread it later. *Which means that it must have a
defined format, and just dumping the bits doesn't work.
I mostly agree, but there are exceptions, and they are not THAT few.
One apparant exception is databases: if you want high performance and
reliability, there is no way out of writing data explicitly to disk
and doing so in a binary format. Of course, portability suffers but
you don't want to port to exoteric machines anyway.

/Peter
Sep 1 '08 #18
Ian Collins wrote:
> If you write some values to a file eg. with fwrite(), it can make a
difference.

Not if you use an endian neutral file system.
fwrite() writes a byte array to the file. How can the file system
"know" what should be "little endian" or "big endian" in a raw byte
array? It can't.
Sep 1 '08 #19
On Sep 1, 10:43 pm, Ian Collins <ian-n...@hotmail.comwrote:
Juha Nieminen wrote:
James Kanze wrote:
> (OTOH, would endianess have any meaning in a system where they have
the same size?)
Does it really have any meaning internally even when the sizes
are different?
If you write some values to a file eg. with fwrite(), it can make a
difference.
Not if you use an endian neutral file system.
I'm not sure I understand. I always assumed that all file
systems were endian neutral, since they all (the ones I know of,
anyway) manipulate bytes, and nothing else. (This is, in fact,
required by the C and C++ standards: wfstream reads and writes
bytes, not wchar_t.)

And fwrite() (or ostream::write()) definitely just dump the
bits, which only works if you've preformatted the data they are
writing.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 2 '08 #20
James Kanze wrote:
On Sep 1, 10:43 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Juha Nieminen wrote:
>>James Kanze wrote:
(OTOH, would endianess have any meaning in a system where they have
the same size?)
Does it really have any meaning internally even when the sizes
are different?
>> If you write some values to a file eg. with fwrite(), it can make a
difference.
>Not if you use an endian neutral file system.

I'm not sure I understand. I always assumed that all file
systems were endian neutral, since they all (the ones I know of,
anyway) manipulate bytes, and nothing else. (This is, in fact,
required by the C and C++ standards: wfstream reads and writes
bytes, not wchar_t.)
I know, I posted too soon.

The data may be endian neutral, but the file system's own house keeping
data may not be. For example you couldn't take a UFS disk form a Sparc
system and read it on an x86 one.

--
Ian Collins.
Sep 2 '08 #21
On Sep 2, 12:02 pm, Ian Collins <ian-n...@hotmail.comwrote:
James Kanze wrote:
On Sep 1, 10:43 pm, Ian Collins <ian-n...@hotmail.comwrote:
Juha Nieminen wrote:
James Kanze wrote:
(OTOH, would endianess have any meaning in a system where they have
the same size?)
Does it really have any meaning internally even when the sizes
are different?
> If you write some values to a file eg. with fwrite(), it can make a
difference.
Not if you use an endian neutral file system.
I'm not sure I understand. I always assumed that all file
systems were endian neutral, since they all (the ones I know of,
anyway) manipulate bytes, and nothing else. (This is, in fact,
required by the C and C++ standards: wfstream reads and writes
bytes, not wchar_t.)
I know, I posted too soon.
The data may be endian neutral, but the file system's own
house keeping data may not be. For example you couldn't take
a UFS disk form a Sparc system and read it on an x86 one.
At the system level, I can see this. I don't expect to take a
disk from one machine, plug it into another, and have it work
(although there's really no reason why not---we expected it to
work with floppies). In the same vein, I don't expect the
binary image of the system to boot correctly other than on the
system for which it was generated. But how many programs are
writing executables (or even object files) to the system, or are
accessing the low level maintenance data on the disk?

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 2 '08 #22
James Kanze wrote:
On Sep 2, 12:02 pm, Ian Collins <ian-n...@hotmail.comwrote:
>James Kanze wrote:
>>On Sep 1, 10:43 pm, Ian Collins <ian-n...@hotmail.comwrote:
Juha Nieminen wrote:
James Kanze wrote:
>> (OTOH, would endianess have any meaning in a system where they have
>>the same size?)
>Does it really have any meaning internally even when the sizes
>are different?
>>>> If you write some values to a file eg. with fwrite(), it can make a
difference.
>>>Not if you use an endian neutral file system.
>>I'm not sure I understand. I always assumed that all file
systems were endian neutral, since they all (the ones I know of,
anyway) manipulate bytes, and nothing else. (This is, in fact,
required by the C and C++ standards: wfstream reads and writes
bytes, not wchar_t.)
>I know, I posted too soon.
>The data may be endian neutral, but the file system's own
house keeping data may not be. For example you couldn't take
a UFS disk form a Sparc system and read it on an x86 one.

At the system level, I can see this. I don't expect to take a
disk from one machine, plug it into another, and have it work
(although there's really no reason why not---we expected it to
work with floppies).
If you want to do that, *then* you use an endian neutral file system!

--
Ian Collins.
Sep 2 '08 #23
On Aug 27, 7:27*am, Niranjan <guruof...@gmail.comwrote:
I have this program :

void main()
{
* * int i=1;
* * if((*(char*)&i)==1)
* * * * *printf("The machine is little endian.");
* * else
* * * * *printf("The machine is big endian.");

}

This program tells me if the machine uses big endian or little endian
format.
But I am not able to understand the working of this program. Can
someone please explain the working.

Thanks in advance.

Thanks,
Niranjan.
The following article explains big and little endian byte ordering:

http://www.eventhelix.com/RealtimeMa...ndOrdering.htm

--
http://www.EventHelix.com/EventStudio
Sequence diagram based systems engineering tool
Sep 4 '08 #24

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: hicham | last post by:
Hi, I am looking for help, i would like to know how can i use the endian.h and config.h to convert compiled files under solaris from BIG-ENDIAN to compiled files LITTLE-ENDIAN. I am working...
3
by: Joe C | last post by:
I have some code that performs bitwise operations on files. I'm trying to make the code portable on different endian systems. This is not work/school related...just trying to learn/understand. ...
8
by: Perception | last post by:
Hello all, If I have a C-like data structure such that struct Data { int a; //16-bit value char; //3 ASCII characters int b; //32-bit value int c; //24-bit value }
14
by: ThazKool | last post by:
I want to see if this code works the way it should on a Big-Endian system. Also if anyone has any ideas on how determine this at compile-time so that I use the right decoding or encoding...
2
by: bhatia | last post by:
Hello all, If I have a C-like data structure such that struct Data { int a; //16-bit value char; //3 ASCII characters int b; //32-bit value int c; //24-bit value }
33
by: raghu | last post by:
Is it possible to know whether a system is little endian or big endian by writing a C program? If so, can anyone please give me the idea to approach... Thanks a ton. Regards, Raghu
8
by: ma740988 | last post by:
Data stored on a storage device is byte swapped. The data is big endian and my PC is little. At issue: There's a composite type ( a header ) at the front of the files that I'm trying to read in....
6
by: Javier | last post by:
Hello people, I'm recoding a library that made a few months ago, and now that I'm reading what I wrote I have some questions. My program reads black and white images from a bitmap (BMP 24bpp...
23
by: guthena | last post by:
Write a small C program to determine whether a machine's type is little-endian or big-endian.
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.