Bit-fields in unsigned short

Discussion in 'C Programming' started by dspfun, Mar 9, 2011.

  1. dspfun

    dspfun Guest

    Hi,

    I want to use bit-fields in unsigned short types since it makes code a
    lot easier to read and I don't have to do bit-masks and bit-shifts to
    access the individual bit-fields.

    However, it seems as C99 only allows bit-fields for unsigned char and
    unsigned int, and bit-fields in unsigned short is a GCC extension.

    I get the following compilation warning

    >gcc -Wall -pedantic bit_field_unsigned_short_test.c

    bit_field_unsigned_short_test.c:6: warning: type of bit-field 'field1'
    is a GCC extension
    bit_field_unsigned_short_test.c:7: warning: type of bit-field 'field2'
    is a GCC extension
    bit_field_unsigned_short_test.c:8: warning: type of bit-field 'field3'
    is a GCC extension

    When I compile the following code:


    >gcc -Wall -pedantic bit_field_unsigned_short_test.c

    bit_field_unsigned_short_test.c: In function 'main':
    bit_field_unsigned_short_test.c:8: warning: type of bit-field 'field1'
    is a GCC extension
    bit_field_unsigned_short_test.c:9: warning: type of bit-field 'field2'
    is a GCC extension
    bit_field_unsigned_short_test.c:10: warning: type of bit-field
    'field3' is a GCC extension

    How can I use bitfields in unsigned short without getting the warnings
    about bit-fields and still use -pedantic flag?

    Brs,
    Markus
     
    dspfun, Mar 9, 2011
    #1
    1. Advertising

  2. dspfun <> writes:

    > I want to use bit-fields in unsigned short types since it makes code a
    > lot easier to read and I don't have to do bit-masks and bit-shifts to
    > access the individual bit-fields.


    It's worth noting that the semantics are different. Using shifts and/or
    masks gives you sequences of bits with known value or significance
    whereas how bit-fields are packed into a struct is up to the compiler.
    This does not matter so much if your code if aimed at one compiler only,
    but you still need to take care that compiler options (or versions)
    don't affect the packing.

    > However, it seems as C99 only allows bit-fields for unsigned char and
    > unsigned int, and bit-fields in unsigned short is a GCC extension.


    C99 allow lots of types but it only insists that an implementation
    support _Bool along with signed and unsigned int.

    > I get the following compilation warning
    >
    >>gcc -Wall -pedantic bit_field_unsigned_short_test.c

    > bit_field_unsigned_short_test.c:6: warning: type of bit-field 'field1'
    > is a GCC extension
    > bit_field_unsigned_short_test.c:7: warning: type of bit-field 'field2'
    > is a GCC extension
    > bit_field_unsigned_short_test.c:8: warning: type of bit-field 'field3'
    > is a GCC extension


    That's probably not compiling in C99 mode, by the way.

    > When I compile the following code:
    >
    >>gcc -Wall -pedantic bit_field_unsigned_short_test.c

    > bit_field_unsigned_short_test.c: In function 'main':
    > bit_field_unsigned_short_test.c:8: warning: type of bit-field 'field1'
    > is a GCC extension
    > bit_field_unsigned_short_test.c:9: warning: type of bit-field 'field2'
    > is a GCC extension
    > bit_field_unsigned_short_test.c:10: warning: type of bit-field
    > 'field3' is a GCC extension
    >
    > How can I use bitfields in unsigned short without getting the warnings
    > about bit-fields and still use -pedantic flag?


    What advantage do you hope to get from using unsigned short rather than
    unsigned int for bit-fields? I can't see why you don't want to use
    unsigned int as the type.

    --
    Ben.
     
    Ben Bacarisse, Mar 9, 2011
    #2
    1. Advertising

  3. dspfun

    dspfun Guest

    On 9 mar, 10:40, Ben Bacarisse <> wrote:
    > What advantage do you hope to get from using unsigned short rather than
    > unsigned int for bit-fields?  I can't see why you don't want to use
    > unsigned int as the type.


    The reason is that two bytes are sent from a big endian cpu and "we"
    receive it on a little endian cpu. To access the information in the
    two bytes I declare a struct with bit-fields.

    Brs,
    Markus
     
    dspfun, Mar 9, 2011
    #3
  4. dspfun

    Jens Guest

    On 9 Mrz., 14:34, dspfun <> wrote:

    > The reason is that two bytes are sent from a big endian cpu and "we"
    > receive it on a little endian cpu. To access the information in the
    > two bytes I declare a struct with bit-fields.


    Don't do that. There are appropriate macros hton and ntoh for that
    purpose already.

    Jens
     
    Jens, Mar 9, 2011
    #4
  5. dspfun

    James Kuyper Guest

    On 03/09/2011 08:34 AM, dspfun wrote:
    > On 9 mar, 10:40, Ben Bacarisse<> wrote:
    >> What advantage do you hope to get from using unsigned short rather than
    >> unsigned int for bit-fields? �I can't see why you don't want to use
    >> unsigned int as the type.

    >
    > The reason is that two bytes are sent from a big endian cpu and "we"
    > receive it on a little endian cpu. To access the information in the
    > two bytes I declare a struct with bit-fields.


    The standard deliberately under-specifies the layout of structs, and
    this is particularly true for bit fields. As a result, you cannot
    portably rely upon the bits from the data you're transferring being in
    the same location as the bits corresponding to any particular bit field.
    If portability isn't an issue, then there's no problem; but for
    maximally portable code, your best option is to use a unsigned char
    buffer, and extracting the bits by using shift and mask operations.

    This still isn't perfect: such code usually relies upon CHAR_BITS==8,
    which is also not guaranteed. However, you can at least check at compile
    time whether CHAR_BITS==8, and chose an appropriate alternative if it is
    not. You cannot determine at compile time which bits of a struct
    correspond to a given bit field, though there are ways to do so at run time.

    --
    James Kuyper
     
    James Kuyper, Mar 9, 2011
    #5
  6. dspfun <> writes:

    > On 9 mar, 10:40, Ben Bacarisse <> wrote:
    >> What advantage do you hope to get from using unsigned short rather than
    >> unsigned int for bit-fields?  I can't see why you don't want to use
    >> unsigned int as the type.

    >
    > The reason is that two bytes are sent from a big endian cpu and "we"
    > receive it on a little endian cpu. To access the information in the
    > two bytes I declare a struct with bit-fields.


    That does not help me to see why you think unsigned short will be better
    than unsigned int for the bit-field. Can you show a fragment of code,
    for example, or show what you used to do until you started to consider
    using unsigned short bit-fields?

    --
    Ben.
     
    Ben Bacarisse, Mar 9, 2011
    #6
  7. Kenneth Brody <> writes:
    <snip>
    > It may be worth noting that which bits are used for bit-fields is
    > implementation-defined.
    >
    > 6.7.2.1p10:
    >
    > The order of allocation of bit-fields within a unit (high-order
    > to low-order or low-order to high-order) is implementation-defined.
    >
    > I found this out the hard way some 25+ years ago when porting a
    > program which stored flags in bit-fields, and saved the value to a
    > file. It worked fine until the program was ported to a system which
    > allocated bits the other way.


    A nit-pick if I may... The problem is that the program saved the
    representation rather than the value -- i.e. that it wrote out the bytes
    used by the implementation rather than what they denoted.

    It is possible to store the value of a structure that uses bit-fields in
    a portable manner (by using printf, for example) though the very use of
    bit-fields often suggests an interest in speed and compactness at odds
    with doing so. I suspect that a high proportion of the time, that
    interest is misplaced!

    <snip>
    --
    Ben.
     
    Ben Bacarisse, Mar 9, 2011
    #7
  8. dspfun

    dspfun Guest

    On 9 mar, 14:59, Ben Bacarisse <> wrote:

    > That does not help me to see why you think unsigned short will be better
    > than unsigned int for the bit-field.  Can you show a fragment of code,
    > for example, or show what you used to do until you started to consider
    > using unsigned short bit-fields?


    The data sent from the first CPU is actually 32 bit (unsigned int) and
    on the receiving CPU these 32 bit are casted to a struct with two
    unsigned char (8 bit) and one unsigned short (16 bit).

    I agree with you that it would be better to use a struct with bit-
    fields of an unsigned int (32 bit).

    Thanks for your help!

    Brs,
    Markus
     
    dspfun, Mar 10, 2011
    #8
  9. dspfun

    dspfun Guest

    On 9 mar, 17:57, Ben Bacarisse <> wrote:
    > Kenneth Brody <> writes:
    >
    > <snip>
    >
    > > It may be worth noting that which bits are used for bit-fields is
    > > implementation-defined.

    >
    > > 6.7.2.1p10:

    >
    > >     The order of allocation of bit-fields within a unit (high-order
    > >     to low-order or low-order to high-order) is implementation-defined.

    >
    > > I found this out the hard way some 25+ years ago when porting a
    > > program which stored flags in bit-fields, and saved the value to a
    > > file.  It worked fine until the program was ported to a system which
    > > allocated bits the other way.

    >
    > A nit-pick if I may...  The problem is that the program saved the
    > representation rather than the value -- i.e. that it wrote out the bytes
    > used by the implementation rather than what they denoted.
    >
    > It is possible to store the value of a structure that uses bit-fields in
    > a portable manner (by using printf, for example) though the very use of
    > bit-fields often suggests an interest in speed and compactness at odds
    > with doing so.  I suspect that a high proportion of the time, that
    > interest is misplaced!
    >


    How do you store the value of a structure that uses bit-fields in a
    portable manner?

    For example, the following file uses bit-fields and not masks and
    shifts. Is this according to the C99-standard or implementation
    defined?

    /usr/src/linux-2.6.16.60-0.69.1/include/linux/ip.h

    struct iphdr {
    #if defined(__LITTLE_ENDIAN_BITFIELD)
    __u8 ihl:4,
    version:4;
    #elif defined (__BIG_ENDIAN_BITFIELD)
    __u8 version:4,
    ihl:4;
    #else
    #error "Please fix <asm/byteorder.h>"
    #endif
    __u8 tos;
    __be16 tot_len;
    __be16 id;
    __be16 frag_off;
    __u8 ttl;
    __u8 protocol;
    __u16 check;
    __be32 saddr;
    __be32 daddr;
    /*The options start here. */
    };
     
    dspfun, Mar 10, 2011
    #9
  10. dspfun <> writes:

    > On 9 mar, 14:59, Ben Bacarisse <> wrote:
    >
    >> That does not help me to see why you think unsigned short will be better
    >> than unsigned int for the bit-field.  Can you show a fragment of code,
    >> for example, or show what you used to do until you started to consider
    >> using unsigned short bit-fields?

    >
    > The data sent from the first CPU is actually 32 bit (unsigned int) and
    > on the receiving CPU these 32 bit are casted to a struct with two
    > unsigned char (8 bit) and one unsigned short (16 bit).


    I know what you mean, but you can't cast to a struct type.

    > I agree with you that it would be better to use a struct with bit-
    > fields of an unsigned int (32 bit).


    A bit-field of type unsigned int is better than a bit-field of type
    unsigned short but I have not said (and I would not say) that you should
    use a struct with bit-fields over the one you describe first! You seem
    to be taking a step backwards by using bit-fields for any sort.

    If you need the code to be portable and to deal with different machine
    representations, then using a struct at all is not a good way to impose
    a meaning on a block of data. Since you are talking about sending and
    receiving and have mentioned endianness already, I think you may have
    started by asking the wrong question.

    --
    Ben.
     
    Ben Bacarisse, Mar 10, 2011
    #10
  11. dspfun <> writes:

    > On 9 mar, 17:57, Ben Bacarisse <> wrote:

    <snip>
    >> It is possible to store the value of a structure that uses bit-fields in
    >> a portable manner (by using printf, for example)

    <snip>
    > How do you store the value of a structure that uses bit-fields in a
    > portable manner?


    I am sure you know how it is just that you are currently thinking in
    terms of bits and bytes a have lost sight that these can mean
    something. The simplest way is to print the decimal representation of
    the numerical value of each of the structure's members along with some
    sort of separator:

    struct eg { unsigned int n1 : 4; unsigned int n2 : 4; } s;
    /* ... */
    printf("{%ud,%ud}\n", s.n1, s.n2);

    > For example, the following file uses bit-fields and not masks and
    > shifts. Is this according to the C99-standard or implementation
    > defined?


    I'm sorry but I am not really sure what that means. If you are asking
    if C99 specifies everything about the layout, packing and padding of the
    structure then the answer is no, it does not.

    > /usr/src/linux-2.6.16.60-0.69.1/include/linux/ip.h
    >
    > struct iphdr {
    > #if defined(__LITTLE_ENDIAN_BITFIELD)
    > __u8 ihl:4,
    > version:4;
    > #elif defined (__BIG_ENDIAN_BITFIELD)
    > __u8 version:4,
    > ihl:4;
    > #else
    > #error "Please fix <asm/byteorder.h>"
    > #endif
    > __u8 tos;
    > __be16 tot_len;
    > __be16 id;
    > __be16 frag_off;
    > __u8 ttl;
    > __u8 protocol;
    > __u16 check;
    > __be32 saddr;
    > __be32 daddr;
    > /*The options start here. */
    > };


    --
    Ben.
     
    Ben Bacarisse, Mar 10, 2011
    #11
  12. dspfun

    James Kuyper Guest

    On 03/10/2011 03:46 AM, dspfun wrote:
    > On 9 mar, 17:57, Ben Bacarisse<> wrote:
    >> Kenneth Brody<> writes:
    >>
    >> <snip>
    >>
    >>> It may be worth noting that which bits are used for bit-fields is
    >>> implementation-defined.

    >>
    >>> 6.7.2.1p10:

    >>
    >>> � � The order of allocation of bit-fields within a unit (high-order
    >>> � � to low-order or low-order to high-order) is implementation-defined.

    >>
    >>> I found this out the hard way some 25+ years ago when porting a
    >>> program which stored flags in bit-fields, and saved the value to a
    >>> file. �It worked fine until the program was ported to a system which
    >>> allocated bits the other way.

    >>
    >> A nit-pick if I may... �The problem is that the program saved the
    >> representation rather than the value -- i.e. that it wrote out the bytes
    >> used by the implementation rather than what they denoted.

    ....
    > How do you store the value of a structure that uses bit-fields in a
    > portable manner?


    In a world where CHAR_BITS is not required to be 8, and there's no
    universal standard for character encoding, perfect portability is not
    possible. In his response, Ben has described one approach. Another is to
    write the fields to an array of unsigned char, assuming that
    CHAR_BITS==8 (and testing that assumption with #if !), forcing precisely
    the endianness required by your application for multi-byte fields, and
    forcing the bit fields into precisely the desired portion of the desired
    bytes.

    > For example, the following file uses bit-fields and not masks and
    > shifts. Is this according to the C99-standard or implementation
    > defined?
    >
    > /usr/src/linux-2.6.16.60-0.69.1/include/linux/ip.h
    >
    > struct iphdr {
    > #if defined(__LITTLE_ENDIAN_BITFIELD)
    > __u8 ihl:4,


    Every identifier in this struct that starts with "__" violates the name
    space reserved to the implementation. That's OK, if ip.h is one of that
    implementation's extensions to standard C; but keep in mind that it's
    not permitted for use code.

    > version:4;
    > #elif defined (__BIG_ENDIAN_BITFIELD)
    > __u8 version:4,
    > ihl:4;
    > #else
    > #error "Please fix<asm/byteorder.h>"


    asm/byteorder.h is also not part of the C standard.

    > #endif
    > __u8 tos;
    > __be16 tot_len;
    > __be16 id;
    > __be16 frag_off;
    > __u8 ttl;
    > __u8 protocol;
    > __u16 check;
    > __be32 saddr;
    > __be32 daddr;
    > /*The options start here. */
    > };


    unsigned char buffer[20]; // assuming I counted right.

    buffer[0] = ihl*16+version;
    buffer[1] = tos;
    buffer[2] = tot_len/256;
    buffer[3] = tot_len%256;
    // etc.

    It's slow and nasty, but it's more portable than relying upon things
    about the layout of structures that are not guaranteed by the C
    standard, and more compact than the text-oriented approach described by
    Ben. His approach also allows the output to be read by human beings,
    whereas this does not.

    --
    James Kuyper
     
    James Kuyper, Mar 10, 2011
    #12
  13. dspfun <> writes:
    > On 9 mar, 14:59, Ben Bacarisse <> wrote:
    >> That does not help me to see why you think unsigned short will be better
    >> than unsigned int for the bit-field.  Can you show a fragment of code,
    >> for example, or show what you used to do until you started to consider
    >> using unsigned short bit-fields?

    >
    > The data sent from the first CPU is actually 32 bit (unsigned int) and
    > on the receiving CPU these 32 bit are casted to a struct with two
    > unsigned char (8 bit) and one unsigned short (16 bit).
    >
    > I agree with you that it would be better to use a struct with bit-
    > fields of an unsigned int (32 bit).


    If the members of the struct on the receiving end are two 8-bit unsigned
    chars and one unsigned 16-bit short, why are you considering using
    bit-fields at all? Do you mena that you're extracting individual
    bits from the unsigned short member?

    As Ben said, it would be *extremely* helpful if you could show us some
    actual code.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Mar 10, 2011
    #13
  14. dspfun

    dspfun Guest

    On 10 mar, 17:28, Keith Thompson <> wrote:

    > As Ben said, it would be *extremely* helpful if you could show us some
    > actual code.


    Consider an example with the following 32-bits containing 6 different
    bit-fields that I want to send from a big-endian cpu to a little
    endian cpu:

    -----------------------------------
    typedef struct my_struct {
    unsigned int f1:1;
    unsigned int f2:4;
    unsigned int f3:7;
    unsigned int f4:3;
    unsigned int f5:12;
    unsigned int f6:5;
    }my_struct_t;

    my_struct_t test_struct;
    test_struct.f1 = 0x1;
    test_struct.f2 = 0x3;
    test_struct.f3 = 0x55;
    test_struct.f4 = 0x2;
    test_struct.f5 = 0x66;
    test_struct.f6 = 0x4;
    -----------------------------------

    What is the best/most "maintainable" way send and access this data
    between the cpus? I guess using bit-fields provides for clearer code
    compared to using an unsigned long in (32 bit) and do bit-masks and
    bit-shifts.

    Brs,
    Markus
     
    dspfun, Mar 11, 2011
    #14
  15. dspfun <> writes:
    > On 10 mar, 17:28, Keith Thompson <> wrote:
    >> As Ben said, it would be *extremely* helpful if you could show us some
    >> actual code.

    >
    > Consider an example with the following 32-bits containing 6 different
    > bit-fields that I want to send from a big-endian cpu to a little
    > endian cpu:
    >
    > -----------------------------------
    > typedef struct my_struct {
    > unsigned int f1:1;
    > unsigned int f2:4;
    > unsigned int f3:7;
    > unsigned int f4:3;
    > unsigned int f5:12;
    > unsigned int f6:5;
    > }my_struct_t;
    >
    > my_struct_t test_struct;
    > test_struct.f1 = 0x1;
    > test_struct.f2 = 0x3;
    > test_struct.f3 = 0x55;
    > test_struct.f4 = 0x2;
    > test_struct.f5 = 0x66;
    > test_struct.f6 = 0x4;
    > -----------------------------------
    >
    > What is the best/most "maintainable" way send and access this data
    > between the cpus? I guess using bit-fields provides for clearer code
    > compared to using an unsigned long in (32 bit) and do bit-masks and
    > bit-shifts.


    Your original question was about unsigned short bit fields.
    There's nothing suggesting that in your example.

    Certainly bit fields make for more easily readable code than shifting
    and masking; it lets you assign names to the individual components.
    (For shifts and masks, macros can help, but the code will still
    look a little ugly.) But the question is, how can you be sure that
    the layout machine A is sending matches the layout that machine B
    is expecting?

    As several people have mentioned, the standard does not completely
    specify how bit fields are laid out. You can't be sure that the
    above declaration will result in the same bit-level layout on two
    different systems.

    If your two machines are identical, with the same C implementation,
    you can use whatever data structure you like and transmit it as
    raw binary (as long as there are no pointers). But you're going
    to have a lot of work to do when you later expand the system to
    include some other machine.

    Even sending 32-bit integers is non-portable. You can probably
    rely on 2's-complement, but byte ordering can easily differ.

    The most portable way to transmit data is probably as plain text
    using a restricted character set. A sequence of 8-bit bytes is
    nearly as good, assuming CHAR_BIT==8 on both ends.

    My suggestion: first define the layout of the data you want to
    transmit in terms of sequences of 8-bit bytes, then figure out how
    to represent it in C.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Mar 11, 2011
    #15
  16. On Thu, 10 Mar 2011 08:46:49 UTC, dspfun <> wrote:

    > How do you store the value of a structure that uses bit-fields in a
    > portable manner?


    Impossible mission. You have simply no chance to get sure that 2
    different implementations are using the same layout of bitfields.

    > For example, the following file uses bit-fields and not masks and
    > shifts. Is this according to the C99-standard or implementation
    > defined?


    No. C (any version) gives an implementation any freedom it needs to
    define the layout of bitfields as it likes. This may even change from
    one version to the next one. It may change frome one compiler to
    other.

    When you have to exchange data between different computers with
    different CPUs or even different OSes or different compilers you can't
    exchange bitfields. You may fail by exchange higher values as bytes.
    The best chance to get that done well is by either convert binary<
    data to text and back (whereas even that can fail when they are using
    different codings for text) or you'll use some vfunctions your network
    APIs gives you on both sites.



    --
    Tschau/Bye
    Herbert

    Visit http://www.ecomstation.de the home of german eComStation
    eComStation 2.0 ist da!
     
    Herbert Rosenau, Mar 11, 2011
    #16
  17. dspfun

    dspfun Guest

    On 11 mar, 17:07, Keith Thompson <> wrote:

    > As several people have mentioned, the standard does not completely
    > specify how bit fields are laid out.  You can't be sure that the
    > above declaration will result in the same bit-level layout on two
    > different systems.


    So how come the Internet Protocol suite work so well? When looking
    briefly at the Linux IP-stack it appears to be using bit-fields for,
    for example, the IP-header.

    Brs,
    Markus
     
    dspfun, Mar 11, 2011
    #17
  18. dspfun

    Ben Pfaff Guest

    dspfun <> writes:

    > On 11 mar, 17:07, Keith Thompson <> wrote:
    >
    >> As several people have mentioned, the standard does not completely
    >> specify how bit fields are laid out.  You can't be sure that the
    >> above declaration will result in the same bit-level layout on two
    >> different systems.

    >
    > So how come the Internet Protocol suite work so well? When looking
    > briefly at the Linux IP-stack it appears to be using bit-fields for,
    > for example, the IP-header.


    First, Linux is not written in portable C. It targets specific
    architectures and C implementations.

    Second, even with those assumptions Linux has to deal with
    multiple bit-field orders, e.g. from include/linux/ip.h:

    struct iphdr {
    #if defined(__LITTLE_ENDIAN_BITFIELD)
    __u8 ihl:4,
    version:4;
    #elif defined (__BIG_ENDIAN_BITFIELD)
    __u8 version:4,
    ihl:4;
    #else
    #error "Please fix <asm/byteorder.h>"
    #endif
    __u8 tos;
    __be16 tot_len;
    __be16 id;
    __be16 frag_off;
    __u8 ttl;
    __u8 protocol;
    __sum16 check;
    __be32 saddr;
    __be32 daddr;
    /*The options start here. */
    };

    --
    Ben Pfaff
    http://benpfaff.org
     
    Ben Pfaff, Mar 11, 2011
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    4
    Views:
    867
    Kaz Kylheku
    Oct 17, 2006
  2. fancyerii
    Replies:
    21
    Views:
    1,619
    Roedy Green
    Nov 5, 2007
  3. Ioannis Vranos

    unsigned short, short literals

    Ioannis Vranos, Mar 4, 2008, in forum: C Programming
    Replies:
    5
    Views:
    732
    Eric Sosman
    Mar 5, 2008
  4. Replies:
    3
    Views:
    462
    James Kanze
    Nov 19, 2008
  5. pozz
    Replies:
    12
    Views:
    796
    Tim Rentsch
    Mar 20, 2011
Loading...

Share This Page