union with packed struct

Discussion in 'C Programming' started by ccwork, Mar 4, 2005.

  1. ccwork

    ccwork Guest

    Hi all,
    Here is a sample code segment:
    ....
    typedef PACKED struct
    {
    union
    {
    PACKED struct
    {
    char red:1;
    char green:1;
    char blue:1;
    } color_bit;
    char color;
    } color_u;
    } color_t;

    color_t color;
    ....
    My question is: which bit in "color.color_u.color" reflect
    "color.color_u.color_bit.red", "color.color_u.color_bit.green" and
    "color.color_u.color_bit.blue"? Is this well defined?
    In other words, if I set "color.color_u.color_bit.red" as 0,
    "color.color_u.color_bit.green" as 0 and "color.color_u.color_bit.blue"
    as 1, What will be "color.color_u.color"? is it 0x04?
     
    ccwork, Mar 4, 2005
    #1
    1. Advertising

  2. ccwork

    Jack Klein Guest

    On 3 Mar 2005 22:10:31 -0800, "ccwork" <> wrote in
    comp.lang.c:

    > Hi all,
    > Here is a sample code segment:


    Actually, it is an illegal code segment.

    > ...
    > typedef PACKED struct
    > {
    > union
    > {
    > PACKED struct


    In the first place, the typedef is not complete so you can't use.
    Secondly, you appear to be trying to define a type that contains an
    instance of itself as a member.

    > {
    > char red:1;
    > char green:1;
    > char blue:1;
    > } color_bit;


    Also note that prior to the 1999 version of the C standard, the only
    allowed types for bit-field members is signed or unsigned int. C99
    allows, but does not require, implementations to accept other integer
    types.

    > char color;
    > } color_u;
    > } color_t;
    >
    > color_t color;


    Next time try posting code that will actually pass through a C
    compiler without error.

    > ...
    > My question is: which bit in "color.color_u.color" reflect
    > "color.color_u.color_bit.red", "color.color_u.color_bit.green" and
    > "color.color_u.color_bit.blue"? Is this well defined?
    > In other words, if I set "color.color_u.color_bit.red" as 0,
    > "color.color_u.color_bit.green" as 0 and "color.color_u.color_bit.blue"
    > as 1, What will be "color.color_u.color"? is it 0x04?


    Almost everything about bit-fields is implementation defined. It is
    entirely up to your compiler as to how it places the bits in the type
    it uses for storage. Check your compiler's documentation.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Mar 4, 2005
    #2
    1. Advertising

  3. ccwork

    Eric Sosman Guest

    ccwork wrote:

    > Hi all,
    > Here is a sample code segment:
    > ...
    > typedef PACKED struct


    What is `PACKED'? It isn't a C construct -- it looks
    like it's probably a #defined macro that expands to (one
    would guess) some kind of implementation-specific extension
    to C like `__attribute__((packed))'. If so, you'll need to
    consult your implementation's documentation to find out
    what's going on, because it isn't C.

    Well, it *could* be C, if `PACKED' expands to something
    like `volatile' or `const' or nothing at all. In what
    follows, I'll assume that's the case.

    > {
    > union
    > {
    > PACKED struct
    > {
    > char red:1;
    > char green:1;
    > char blue:1;
    > } color_bit;
    > char color;
    > } color_u;
    > } color_t;
    >
    > color_t color;
    > ...
    > My question is: which bit in "color.color_u.color" reflect
    > "color.color_u.color_bit.red", "color.color_u.color_bit.green" and
    > "color.color_u.color_bit.blue"? Is this well defined?


    Not by the C language. The compiler has great freedom
    in how it chooses to arrange bit-fields within a struct.
    Different compilers will arrange things differently.

    > In other words, if I set "color.color_u.color_bit.red" as 0,
    > "color.color_u.color_bit.green" as 0 and "color.color_u.color_bit.blue"
    > as 1, What will be "color.color_u.color"? is it 0x04?


    Not necessarily. In fact, it's not guaranteed that
    `color.color_u.color' will have a valid value at all: unions
    are frequently (ab)used for this sort of type punning, but
    the language doesn't promise that anything reasonable will
    happen if you try it.

    If you want to represent a color as three bits in a
    `char', you're better off using bitwise operators with
    pre-#defined (or enum-erated) masks:

    typedef unsigned char color_t;
    #define COLOR_RED 1
    #define COLOR_GREEN 2
    #define COLOR_BLUE 4
    #define COLOR_YELLOW (COLOR_GREEN | COLOR_RED)
    ...

    --
    Eric Sosman
    lid
     
    Eric Sosman, Mar 4, 2005
    #3
  4. ccwork

    ccwork Guest

    Hi,
    How about assign "color.color_u.color_bit.red" to something other
    than 0 and 1? Say color.color_u.color_bit.red=20. What will happen?
    How about assign color.color_u.color_bit.red=(some expression) &&
    (another expression)?

    Actually all these are code from a senior engineer and I am helping
    him...

    Eric Sosman wrote:
    > ccwork wrote:
    >
    > > Hi all,
    > > Here is a sample code segment:
    > > ...
    > > typedef PACKED struct

    >
    > What is `PACKED'? It isn't a C construct -- it looks
    > like it's probably a #defined macro that expands to (one
    > would guess) some kind of implementation-specific extension
    > to C like `__attribute__((packed))'. If so, you'll need to
    > consult your implementation's documentation to find out
    > what's going on, because it isn't C.
    >
    > Well, it *could* be C, if `PACKED' expands to something
    > like `volatile' or `const' or nothing at all. In what
    > follows, I'll assume that's the case.
    >
    > > {
    > > union
    > > {
    > > PACKED struct
    > > {
    > > char red:1;
    > > char green:1;
    > > char blue:1;
    > > } color_bit;
    > > char color;
    > > } color_u;
    > > } color_t;
    > >
    > > color_t color;
    > > ...
    > > My question is: which bit in "color.color_u.color" reflect
    > > "color.color_u.color_bit.red", "color.color_u.color_bit.green" and
    > > "color.color_u.color_bit.blue"? Is this well defined?

    >
    > Not by the C language. The compiler has great freedom
    > in how it chooses to arrange bit-fields within a struct.
    > Different compilers will arrange things differently.
    >
    > > In other words, if I set "color.color_u.color_bit.red" as 0,
    > > "color.color_u.color_bit.green" as 0 and

    "color.color_u.color_bit.blue"
    > > as 1, What will be "color.color_u.color"? is it 0x04?

    >
    > Not necessarily. In fact, it's not guaranteed that
    > `color.color_u.color' will have a valid value at all: unions
    > are frequently (ab)used for this sort of type punning, but
    > the language doesn't promise that anything reasonable will
    > happen if you try it.
    >
    > If you want to represent a color as three bits in a
    > `char', you're better off using bitwise operators with
    > pre-#defined (or enum-erated) masks:
    >
    > typedef unsigned char color_t;
    > #define COLOR_RED 1
    > #define COLOR_GREEN 2
    > #define COLOR_BLUE 4
    > #define COLOR_YELLOW (COLOR_GREEN | COLOR_RED)
    > ...
    >
    > --
    > Eric Sosman
    > lid
     
    ccwork, Mar 7, 2005
    #4
  5. packed structures means to put the next one emmediately following the first
    one, instead of on 64 bit boundaries.

    You should note that structs, unions, and classess are designed to help the
    programmer not the computer. You will find that aligning your data within
    each Struct to 64 bit boundaries allows you a few more machine cycles than
    all the tidbitley wringing done to code to "optimize" it.

    Keep in mind that a struct is just an int[], with mapping handles for the
    "Programmer".

    I hope you gain something from this.

    "ccwork" <> wrote in message
    news:...
    > Hi,
    > How about assign "color.color_u.color_bit.red" to something other
    > than 0 and 1? Say color.color_u.color_bit.red=20. What will happen?
    > How about assign color.color_u.color_bit.red=(some expression) &&
    > (another expression)?
    >
    > Actually all these are code from a senior engineer and I am helping
    > him...
    >
    > Eric Sosman wrote:
    >> ccwork wrote:
    >>
    >> > Hi all,
    >> > Here is a sample code segment:
    >> > ...
    >> > typedef PACKED struct

    >>
    >> What is `PACKED'? It isn't a C construct -- it looks
    >> like it's probably a #defined macro that expands to (one
    >> would guess) some kind of implementation-specific extension
    >> to C like `__attribute__((packed))'. If so, you'll need to
    >> consult your implementation's documentation to find out
    >> what's going on, because it isn't C.
    >>
    >> Well, it *could* be C, if `PACKED' expands to something
    >> like `volatile' or `const' or nothing at all. In what
    >> follows, I'll assume that's the case.
    >>
    >> > {
    >> > union
    >> > {
    >> > PACKED struct
    >> > {
    >> > char red:1;
    >> > char green:1;
    >> > char blue:1;
    >> > } color_bit;
    >> > char color;
    >> > } color_u;
    >> > } color_t;
    >> >
    >> > color_t color;
    >> > ...
    >> > My question is: which bit in "color.color_u.color" reflect
    >> > "color.color_u.color_bit.red", "color.color_u.color_bit.green" and
    >> > "color.color_u.color_bit.blue"? Is this well defined?

    >>
    >> Not by the C language. The compiler has great freedom
    >> in how it chooses to arrange bit-fields within a struct.
    >> Different compilers will arrange things differently.
    >>
    >> > In other words, if I set "color.color_u.color_bit.red" as 0,
    >> > "color.color_u.color_bit.green" as 0 and

    > "color.color_u.color_bit.blue"
    >> > as 1, What will be "color.color_u.color"? is it 0x04?

    >>
    >> Not necessarily. In fact, it's not guaranteed that
    >> `color.color_u.color' will have a valid value at all: unions
    >> are frequently (ab)used for this sort of type punning, but
    >> the language doesn't promise that anything reasonable will
    >> happen if you try it.
    >>
    >> If you want to represent a color as three bits in a
    >> `char', you're better off using bitwise operators with
    >> pre-#defined (or enum-erated) masks:
    >>
    >> typedef unsigned char color_t;
    >> #define COLOR_RED 1
    >> #define COLOR_GREEN 2
    >> #define COLOR_BLUE 4
    >> #define COLOR_YELLOW (COLOR_GREEN | COLOR_RED)
    >> ...
    >>
    >> --
    >> Eric Sosman
    >> lid

    >
     
    DHOLLINGSWORTH2, Mar 8, 2005
    #5
  6. On Mon, 7 Mar 2005 23:37:20 -0600, in comp.lang.c , "DHOLLINGSWORTH2"
    <> wrote:

    >packed structures means to put the next one emmediately following the first
    >one, instead of on 64 bit boundaries.


    Note that there's no requirement from the C Standard for data to be aligned
    on 64-bit boundaries. This woudn't make much sense on a 36-bit machine.

    >Keep in mind that a struct is just an int[], with mapping handles for the
    >"Programmer".


    Nonsense.

    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

    ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----
     
    Mark McIntyre, Mar 8, 2005
    #6
  7. ccwork

    ccwork Guest

    Mark McIntyre wrote:
    > On Mon, 7 Mar 2005 23:37:20 -0600, in comp.lang.c , "DHOLLINGSWORTH2"
    > <> wrote:
    >
    > >packed structures means to put the next one emmediately following

    the first
    > >one, instead of on 64 bit boundaries.

    >
    > Note that there's no requirement from the C Standard for data to be

    aligned
    > on 64-bit boundaries. This woudn't make much sense on a 36-bit

    machine.
    >
    > >Keep in mind that a struct is just an int[], with mapping handles

    for the
    > >"Programmer".

    >
    > Nonsense.


    Can you elaborate this further?

    > --
    > Mark McIntyre
    > CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    > CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
    >
    > ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet

    News==----
    > http://www.newsfeeds.com The #1 Newsgroup Service in the World!

    120,000+ Newsgroups
    > ----= East and West-Coast Server Farms - Total Privacy via Encryption

    =----
     
    ccwork, Mar 9, 2005
    #7
  8. I'm kind of wondering what you think is nonsense about it.
    While it is true that the actual boundary, and size is dependent on the HW.
    The idea is still the same.

    And I'm afraid that what you call "nonsense", is actually refered to as a
    FLAT MEMORY MODEL.

    That means that 20 bytes is 20 bytes. it means that all of the memory on
    your system is in the form of :
    int[MEMORY_SIZE]
    With int, being the size of the register Accessing memory, The actual # of
    bits read in. I dont how else to describe it to you.

    But
    struct _tegname{
    char some_of_ this_nonsense;
    int * Some_of_that_nonsense;
    short Some_mmore_Nonsense;
    ....
    }, NONSENSE;

    is stored in that FLAT MEMORY MODEL.
    ie: int[];



    "ccwork" <> wrote in message
    news:...
    >
    > Mark McIntyre wrote:
    >> On Mon, 7 Mar 2005 23:37:20 -0600, in comp.lang.c , "DHOLLINGSWORTH2"
    >> <> wrote:
    >>
    >> >packed structures means to put the next one emmediately following

    > the first
    >> >one, instead of on 64 bit boundaries.

    >>
    >> Note that there's no requirement from the C Standard for data to be

    > aligned
    >> on 64-bit boundaries. This woudn't make much sense on a 36-bit

    > machine.
    >>
    >> >Keep in mind that a struct is just an int[], with mapping handles

    > for the
    >> >"Programmer".

    >>
    >> Nonsense.

    >
    > Can you elaborate this further?
    >
    >> --
    >> Mark McIntyre
    >> CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    >> CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>
    >>
    >> ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet

    > News==----
    >> http://www.newsfeeds.com The #1 Newsgroup Service in the World!

    > 120,000+ Newsgroups
    >> ----= East and West-Coast Server Farms - Total Privacy via Encryption

    > =----
    >
     
    DHOLLINGSWORTH2, Mar 9, 2005
    #8
  9. In article <tDvXd.1029$Qz.700@okepread05>,
    DHOLLINGSWORTH2 <> wrote:
    :And I'm afraid that what you call "nonsense", is actually refered to as a
    :FLAT MEMORY MODEL.

    What you are calling a "flat memory model" is one -particular- flat memory
    model, which does not hold true on all flat memory systems.


    :That means that 20 bytes is 20 bytes. it means that all of the memory on
    :your system is in the form of :
    :int[MEMORY_SIZE]
    :With int, being the size of the register Accessing memory, The actual # of
    :bits read in. I dont how else to describe it to you.

    So then, how do you explain the Honeywell L66 architecture, which
    could store 6 characters per word, 36 bits per word, and had 9 bit bytes?

    You are assuming that all memory is alignable in "int" chunks. That
    isn't true on all architectures: on some architectures (e.g., the L66),
    you need to use different instructions to get at different data types.
    Some architectures store 80 bits per double, and can put doubles
    back to back, and yet for normal operations require that int be aligned
    on 32 bit boundaries.

    :But
    :struct _tegname{
    : char some_of_ this_nonsense;
    : int * Some_of_that_nonsense;
    : short Some_mmore_Nonsense;
    :...
    :}, NONSENSE;

    :is stored in that FLAT MEMORY MODEL.
    :ie: int[];

    Some architectures have pointers which are not the size of int (or
    long) and which can be aligned on different boundaries than int.

    For example, the representation of two of the above in memory
    could have this byte layout:

    0 : some_of_this_nonsense character 0 = int 0 byte 0
    1 : unused padding = int 0 byte 1
    2 : Some_of_that_nonsense byte 0 = int 0 byte 2
    3 : Some_of_that_nonsense byte 1 = int 0 byte 3
    4 : Some_of_that_nonsense byte 2 = int 1 byte 0
    5 : Some_of_that_nonsense byte 3 = int 1 byte 1
    6 : Some_of_that_nonsense byte 4 = int 1 byte 2
    7 : Some_of_that_nonsense byte 5 = int 1 byte 3
    8 : Some_mmore_Nonsense byte 0 = int 2 byte 0
    9 : Some_mmore_Nonsense byte 1 = int 2 byte 1

    A : some_of_this_nonsense2 character 0 = int 2 byte 2
    B : unused padding = int 2 byte 3
    C : Some_of_that_nonsense2 byte 0 = int 3 byte 0
    D : Some_of_that_nonsense2 byte 1 = int 3 byte 1
    E : Some_of_that_nonsense2 byte 2 = int 3 byte 2
    F : Some_of_that_nonsense2 byte 3 = int 3 byte 3
    10: Some_of_that_nonsense2 byte 4 = int 4 byte 0
    11: Some_of_that_nonsense2 byte 5 = int 4 byte 1
    12: Some_mmore_Nonsense2 byte 0 = int 4 byte 2
    13: Some_mmore_Nonsense2 byte 1 = int 4 byte 3

    The architecture could have instructions able to load characters
    from arbitrary bytes, to load 6 byte pointers from 2 byte boundaries,
    to load 2 byte shorts from 2 byte boundaries, and yet might not
    have any instruction to load int from 2 byte boundaries, only
    from 4 byte boundaries. In such an architecture, the structure
    is not representable as an array of int -- not without having
    the array of int include data that belongs to another object!


    If you examine the alignment rules of the Standard, you will
    see that basically there -aren't- any alignment rules in
    the Standard, other than that malloc() shall return a pointer
    which satisfies the alignment rules for all primitive data types.
    sizeof(short) <= sizeof(int) <= sizeof(long)
    but that doesn't tell us anything about how short, int, or long
    must be aligned in memory. Converting a short into an int
    is not necessarily just a matter of moving 0 into the int
    and then MOV.S the short into the "bottom short" of the int:
    it is perfectly acceptable for the achitecture to use
    a complete different set of registers for working with
    shorts and int, with an explicit "extend short to int"
    instruction instruction. (And yes, I really have seen
    architectures with "extend short to int" instructions --
    and no, they weren't synonyms for "sign extend short to
    int".)
    --
    Warning: potentially contains traces of nuts.
     
    Walter Roberson, Mar 9, 2005
    #9
  10. I'm sorry, when you show me a computer with contiguous ram, that has more
    than one memory location for any one given address then you'll have an
    argument.

    Call it what you want :
    somesize[];
    MyCompsRegWidth[];
    MyRamsWordSize[];

    There is a level of comprehension and understanding that I wrongfully
    assumed that every english typing programmer had.

    and yes : int[], char[], word[], WhatHaveYa[];

    is all the same in HW.

    STRUCTS are there for the programmer, not the computer!



    "Walter Roberson" <-cnrc.gc.ca> wrote in message
    news:d0m36j$7qr$...
    > In article <tDvXd.1029$Qz.700@okepread05>,
    > DHOLLINGSWORTH2 <> wrote:
    > :And I'm afraid that what you call "nonsense", is actually refered to as a
    > :FLAT MEMORY MODEL.
    >
    > What you are calling a "flat memory model" is one -particular- flat memory
    > model, which does not hold true on all flat memory systems.
    >
    >
    > :That means that 20 bytes is 20 bytes. it means that all of the memory on
    > :your system is in the form of :
    > :int[MEMORY_SIZE]
    > :With int, being the size of the register Accessing memory, The actual #
    > of
    > :bits read in. I dont how else to describe it to you.
    >
    > So then, how do you explain the Honeywell L66 architecture, which
    > could store 6 characters per word, 36 bits per word, and had 9 bit bytes?
    >
    > You are assuming that all memory is alignable in "int" chunks. That
    > isn't true on all architectures: on some architectures (e.g., the L66),
    > you need to use different instructions to get at different data types.
    > Some architectures store 80 bits per double, and can put doubles
    > back to back, and yet for normal operations require that int be aligned
    > on 32 bit boundaries.
    >
    > :But
    > :struct _tegname{
    > : char some_of_ this_nonsense;
    > : int * Some_of_that_nonsense;
    > : short Some_mmore_Nonsense;
    > :...
    > :}, NONSENSE;
    >
    > :is stored in that FLAT MEMORY MODEL.
    > :ie: int[];
    >
    > Some architectures have pointers which are not the size of int (or
    > long) and which can be aligned on different boundaries than int.
    >
    > For example, the representation of two of the above in memory
    > could have this byte layout:
    >
    > 0 : some_of_this_nonsense character 0 = int 0 byte 0
    > 1 : unused padding = int 0 byte 1
    > 2 : Some_of_that_nonsense byte 0 = int 0 byte 2
    > 3 : Some_of_that_nonsense byte 1 = int 0 byte 3
    > 4 : Some_of_that_nonsense byte 2 = int 1 byte 0
    > 5 : Some_of_that_nonsense byte 3 = int 1 byte 1
    > 6 : Some_of_that_nonsense byte 4 = int 1 byte 2
    > 7 : Some_of_that_nonsense byte 5 = int 1 byte 3
    > 8 : Some_mmore_Nonsense byte 0 = int 2 byte 0
    > 9 : Some_mmore_Nonsense byte 1 = int 2 byte 1
    >
    > A : some_of_this_nonsense2 character 0 = int 2 byte 2
    > B : unused padding = int 2 byte 3
    > C : Some_of_that_nonsense2 byte 0 = int 3 byte 0
    > D : Some_of_that_nonsense2 byte 1 = int 3 byte 1
    > E : Some_of_that_nonsense2 byte 2 = int 3 byte 2
    > F : Some_of_that_nonsense2 byte 3 = int 3 byte 3
    > 10: Some_of_that_nonsense2 byte 4 = int 4 byte 0
    > 11: Some_of_that_nonsense2 byte 5 = int 4 byte 1
    > 12: Some_mmore_Nonsense2 byte 0 = int 4 byte 2
    > 13: Some_mmore_Nonsense2 byte 1 = int 4 byte 3
    >
    > The architecture could have instructions able to load characters
    > from arbitrary bytes, to load 6 byte pointers from 2 byte boundaries,
    > to load 2 byte shorts from 2 byte boundaries, and yet might not
    > have any instruction to load int from 2 byte boundaries, only
    > from 4 byte boundaries. In such an architecture, the structure
    > is not representable as an array of int -- not without having
    > the array of int include data that belongs to another object!
    >
    >
    > If you examine the alignment rules of the Standard, you will
    > see that basically there -aren't- any alignment rules in
    > the Standard, other than that malloc() shall return a pointer
    > which satisfies the alignment rules for all primitive data types.
    > sizeof(short) <= sizeof(int) <= sizeof(long)
    > but that doesn't tell us anything about how short, int, or long
    > must be aligned in memory. Converting a short into an int
    > is not necessarily just a matter of moving 0 into the int
    > and then MOV.S the short into the "bottom short" of the int:
    > it is perfectly acceptable for the achitecture to use
    > a complete different set of registers for working with
    > shorts and int, with an explicit "extend short to int"
    > instruction instruction. (And yes, I really have seen
    > architectures with "extend short to int" instructions --
    > and no, they weren't synonyms for "sign extend short to
    > int".)
    > --
    > Warning: potentially contains traces of nuts.
     
    DHOLLINGSWORTH2, Mar 9, 2005
    #10
  11. In article <RkxXd.1045$Qz.218@okepread05>,
    DHOLLINGSWORTH2 <> wrote:
    :I'm sorry, when you show me a computer with contiguous ram, that has more
    :than one memory location for any one given address then you'll have an
    :argument.

    There are several systems around for which the smallest addressible
    unit is the "word", and there are special instructions necessary
    to extract characters within words. For some of those, a character
    can start at an arbitrary bit position within the word!

    On bitslice architectures, bit-wise packing of structures is
    possible -- e.g., if you had

    typedef struct { unsigned int i:3, char c, int j } s3cj;
    s3cj A[2];

    then the compiler might choose to lay A out in memory as (bitwise)

    iiiccccccccjjjjjjjjjjjjjjjjjjjjj
    jjjjjjjjjjjiiiccccccccjjjjjjjjj
    jjjjjjjjjjjjjjjjjjjjjjj
    0123456789ABCDEF0123456789ABCDEF

    Clearly on such an architecture, the offset to j is not
    a multiple of a byte/word/int/long .

    :and yes : int[], char[], word[], WhatHaveYa[];
    :is all the same in HW.

    Wrong. There has perhaps been an equivilence on all the architectures
    you have worked on, but you have to remember that C is defined in such
    a way as to be implimentable on oddities such as 1's compliment
    machines and embedded microprocessors.

    It isn't uncommon on RISC machines for the actual memory size read or
    written for each access to main memory to be fairly large -- an entire
    "cache line" at a time, where a cache might be (e.g.) 64 bytes. On
    such systems, the smallest individually addressible unit may be the 32
    bit or 64 bit long, with there being extra instructions needed to
    access smaller units.

    As far as the C standard is concerned, there is no problem if, instead
    of the memory being a stream of individually addressible bytes, there
    are addressing modes that take a base address and an index and access
    or store at the appropriate location; e.g., MOV.S A3(D6),D0 could
    perform an index operation into memory, taking the D6'th short from the
    begining of A3, even though that might not fall onto a directly
    addressible boundary.

    If you re-examine what you are allowed to do with pointers, you will
    find that you are not allowed to compare pointers to different
    objects [even of the same type], and that casting a pointer to
    anything other than a "compatible" type is not certain to be
    meaningful. Converting a pointer to (void *) and back again
    is constrained to compare equal to the original, but it is
    legal for different pointer types to be different sizes
    and to hold different internal information.
    --
    "[...] it's all part of one's right to be publicly stupid." -- Dave Smey
     
    Walter Roberson, Mar 9, 2005
    #11
  12. You can slice it by the bit, you can slice it by GiG.

    There is still only one address per Location!

    I have used microproccessors with RISC, with nonrisc, even some with a
    PRogrammable micro code.

    And on every Computer, microproccessor, digital circuit, there is still only
    one location for the specified address, I dont care how big or small a chunk
    you look at. Or on what HW you look at.

    The computer will not change it's abilities to read what the Memory bus can
    put out between members in a struct.
    There is NO physical conection.

    You act like your bits can't possibly be what the HW was designed to
    manipulate.

    Why would you build a 32 bit data bus and say that reading 4 chunks of 8
    bits each were any faster than reading the whole 32.
    would reading 32 chunks of 1 bit, be even faster?

    IT doesn't matter, in memory, the BITS are stored in contiguous groups.

    For example the 486 uses 32 bit registers, the actual indexing is done 8
    bits per address. However reading 4 chars is slower than 1 dword.
    Becuase you read 32 bits for each char read. FACT!

    even on your micropro with bitslicing architecture, lets say you have 16
    bits of data bus, but you only want to use 4 bits. OK you can, ITs still in
    the middle of one huge array of integers. FACT! It's still contiguous.

    And every time you access those 4 bits they are in the same Physical
    location as before.

    I think you may have confused what I was saying with how I was saying it.

    Do you think we should optimize code that only utilized 1/8 of the register,
    or 1/4 of the data bus, whats the point.
    You have to get the code to run twice as fast to make up for only using 1/2
    the registers, 1/2 data bus, etc.
    Thats always going to be true. And that is my point.



    "Walter Roberson" <-cnrc.gc.ca> wrote in message
    news:d0mbtr$i5a$...
    > In article <RkxXd.1045$Qz.218@okepread05>,
    > DHOLLINGSWORTH2 <> wrote:
    > :I'm sorry, when you show me a computer with contiguous ram, that has more
    > :than one memory location for any one given address then you'll have an
    > :argument.
    >
    > There are several systems around for which the smallest addressible
    > unit is the "word", and there are special instructions necessary
    > to extract characters within words. For some of those, a character
    > can start at an arbitrary bit position within the word!
    >
    > On bitslice architectures, bit-wise packing of structures is
    > possible -- e.g., if you had
    >
    > typedef struct { unsigned int i:3, char c, int j } s3cj;
    > s3cj A[2];
    >
    > then the compiler might choose to lay A out in memory as (bitwise)
    >
    > iiiccccccccjjjjjjjjjjjjjjjjjjjjj
    > jjjjjjjjjjjiiiccccccccjjjjjjjjj
    > jjjjjjjjjjjjjjjjjjjjjjj
    > 0123456789ABCDEF0123456789ABCDEF
    >
    > Clearly on such an architecture, the offset to j is not
    > a multiple of a byte/word/int/long .
    >
    > :and yes : int[], char[], word[], WhatHaveYa[];
    > :is all the same in HW.
    >
    > Wrong. There has perhaps been an equivilence on all the architectures
    > you have worked on, but you have to remember that C is defined in such
    > a way as to be implimentable on oddities such as 1's compliment
    > machines and embedded microprocessors.
    >
    > It isn't uncommon on RISC machines for the actual memory size read or
    > written for each access to main memory to be fairly large -- an entire
    > "cache line" at a time, where a cache might be (e.g.) 64 bytes. On
    > such systems, the smallest individually addressible unit may be the 32
    > bit or 64 bit long, with there being extra instructions needed to
    > access smaller units.
    >
    > As far as the C standard is concerned, there is no problem if, instead
    > of the memory being a stream of individually addressible bytes, there
    > are addressing modes that take a base address and an index and access
    > or store at the appropriate location; e.g., MOV.S A3(D6),D0 could
    > perform an index operation into memory, taking the D6'th short from the
    > begining of A3, even though that might not fall onto a directly
    > addressible boundary.
    >
    > If you re-examine what you are allowed to do with pointers, you will
    > find that you are not allowed to compare pointers to different
    > objects [even of the same type], and that casting a pointer to
    > anything other than a "compatible" type is not certain to be
    > meaningful. Converting a pointer to (void *) and back again
    > is constrained to compare equal to the original, but it is
    > legal for different pointer types to be different sizes
    > and to hold different internal information.
    > --
    > "[...] it's all part of one's right to be publicly stupid." -- Dave Smey
     
    DHOLLINGSWORTH2, Mar 9, 2005
    #12
  13. ccwork

    ccwork Guest

    Hi,
    for the struct:

    struct S
    {
    char a;
    char b;
    char c;
    } s;

    According to your meaning that struct is int [], this mean:
    1) ((int *)&s)[0] = s.a
    2) ((int *)&s)[1] = s.b
    3) ((int *)&s)[2] = s.c
    Most likely this is wrong if sizeof(char) < sizeof(int). Walter
    Roberson gave a very good example of bitslice architecture that
    addressess of individual member of a struct can be ANY, not necessarily
    multiple of char/short/int/long.

    DHOLLINGSWORTH2 wrote:
    > You can slice it by the bit, you can slice it by GiG.
    >
    > There is still only one address per Location!
    >
    > I have used microproccessors with RISC, with nonrisc, even some with

    a
    > PRogrammable micro code.
    >
    > And on every Computer, microproccessor, digital circuit, there is

    still only
    > one location for the specified address, I dont care how big or small

    a chunk
    > you look at. Or on what HW you look at.
    >
    > The computer will not change it's abilities to read what the Memory

    bus can
    > put out between members in a struct.
    > There is NO physical conection.
    >
    > You act like your bits can't possibly be what the HW was designed to
    > manipulate.
    >
    > Why would you build a 32 bit data bus and say that reading 4 chunks

    of 8
    > bits each were any faster than reading the whole 32.
    > would reading 32 chunks of 1 bit, be even faster?
    >
    > IT doesn't matter, in memory, the BITS are stored in contiguous

    groups.
    >
    > For example the 486 uses 32 bit registers, the actual indexing is

    done 8
    > bits per address. However reading 4 chars is slower than 1 dword.
    > Becuase you read 32 bits for each char read. FACT!
    >
    > even on your micropro with bitslicing architecture, lets say you have

    16
    > bits of data bus, but you only want to use 4 bits. OK you can, ITs

    still in
    > the middle of one huge array of integers. FACT! It's still

    contiguous.
    >
    > And every time you access those 4 bits they are in the same Physical
    > location as before.
    >
    > I think you may have confused what I was saying with how I was saying

    it.
    >
    > Do you think we should optimize code that only utilized 1/8 of the

    register,
    > or 1/4 of the data bus, whats the point.
    > You have to get the code to run twice as fast to make up for only

    using 1/2
    > the registers, 1/2 data bus, etc.
    > Thats always going to be true. And that is my point.
    >
    >
    >
    > "Walter Roberson" <-cnrc.gc.ca> wrote in message
    > news:d0mbtr$i5a$...
    > > In article <RkxXd.1045$Qz.218@okepread05>,
    > > DHOLLINGSWORTH2 <> wrote:
    > > :I'm sorry, when you show me a computer with contiguous ram, that

    has more
    > > :than one memory location for any one given address then you'll

    have an
    > > :argument.
    > >
    > > There are several systems around for which the smallest addressible
    > > unit is the "word", and there are special instructions necessary
    > > to extract characters within words. For some of those, a character
    > > can start at an arbitrary bit position within the word!
    > >
    > > On bitslice architectures, bit-wise packing of structures is
    > > possible -- e.g., if you had
    > >
    > > typedef struct { unsigned int i:3, char c, int j } s3cj;
    > > s3cj A[2];
    > >
    > > then the compiler might choose to lay A out in memory as (bitwise)
    > >
    > > iiiccccccccjjjjjjjjjjjjjjjjjjjjj
    > > jjjjjjjjjjjiiiccccccccjjjjjjjjj
    > > jjjjjjjjjjjjjjjjjjjjjjj
    > > 0123456789ABCDEF0123456789ABCDEF
    > >
    > > Clearly on such an architecture, the offset to j is not
    > > a multiple of a byte/word/int/long .
    > >
    > > :and yes : int[], char[], word[], WhatHaveYa[];
    > > :is all the same in HW.
    > >
    > > Wrong. There has perhaps been an equivilence on all the

    architectures
    > > you have worked on, but you have to remember that C is defined in

    such
    > > a way as to be implimentable on oddities such as 1's compliment
    > > machines and embedded microprocessors.
    > >
    > > It isn't uncommon on RISC machines for the actual memory size read

    or
    > > written for each access to main memory to be fairly large -- an

    entire
    > > "cache line" at a time, where a cache might be (e.g.) 64 bytes. On
    > > such systems, the smallest individually addressible unit may be the

    32
    > > bit or 64 bit long, with there being extra instructions needed to
    > > access smaller units.
    > >
    > > As far as the C standard is concerned, there is no problem if,

    instead
    > > of the memory being a stream of individually addressible bytes,

    there
    > > are addressing modes that take a base address and an index and

    access
    > > or store at the appropriate location; e.g., MOV.S A3(D6),D0 could
    > > perform an index operation into memory, taking the D6'th short from

    the
    > > begining of A3, even though that might not fall onto a directly
    > > addressible boundary.
    > >
    > > If you re-examine what you are allowed to do with pointers, you

    will
    > > find that you are not allowed to compare pointers to different
    > > objects [even of the same type], and that casting a pointer to
    > > anything other than a "compatible" type is not certain to be
    > > meaningful. Converting a pointer to (void *) and back again
    > > is constrained to compare equal to the original, but it is
    > > legal for different pointer types to be different sizes
    > > and to hold different internal information.
    > > --
    > > "[...] it's all part of one's right to be publicly stupid." --

    Dave Smey
     
    ccwork, Mar 9, 2005
    #13
  14. Walter Roberson wrote:
    > In article <RkxXd.1045$Qz.218@okepread05>,
    > DHOLLINGSWORTH2 <> wrote:


    <large snip>

    >
    > If you re-examine what you are allowed to do with pointers, you will
    > find that you are not allowed to compare pointers to different
    > objects [even of the same type],


    Incorrect:

    6.5.9 Equality operators

    [...]

    6 Two pointers compare equal if and only if both are
    null pointers, both are pointers to the same object
    (including a pointer to an object and a subobject
    at its beginning) or function, both are pointers to
    one past the last element of the same array object,
    or one is a pointer to one past the end of one array
    object and the other is a pointer to the start of a
    different array object that happens to immediately
    follow the first array object in the address space.



    Mark F. Haigh
     
    Mark F. Haigh, Mar 9, 2005
    #14
  15. no,

    what I mean is that

    char * s ="Some text in ram!";

    the text "Some text in ram!" is actually stored in ram.
    in contiguous chunks.

    you could say char s[]; represents an area in ram at s,

    I'M Saying that all of your ram can be looked at like
    int []; instead of some char [], some word[]; etc.

    When you store the data in a form the Hardware naturally proccessess you are
    going to save more clock cycles than you will pull out optimizing your code
    by hand.

    Simple put, Streamlining your code, does more for you than optimizing. When
    you use data structures that are not in anyway equivelant to the native
    operation of your HW.

    char s[] = "Some text in Ram";

    as an int[]; is the same exact pattern in memory;

    as a programmer you would have to unpack the integer to get the individual
    char values. when you use char []; the packing, and unpacking is done
    "behind the scene".

    Lets say you have a struct :

    struct myStruct {
    short x;
    short y;
    short z;
    } coord;

    accessing coord.x means you are loading an intire register with int, and
    croping it to obtain the short portion.

    in effect, incrementing x, y, z means you have loaded at least one of these
    twice, once you through it out, and the second time, you through the rest
    out.

    on a 64 bit machine, Which reads and writes 64 bits at a time, you would
    read in each value, 16 bits, once, and get the other 48 bits with it, crop
    it ( unpack) , increment it, add the 48 bits back in,( pack it ), then save
    it back to ram.

    you could read all 3 shorts at once by alligning your structure on a 64 bit
    boundary, and inc each one in one clock cycle, and similarly in one write
    cycle store all three values back.
    or
    (this was my original statement)
    you can redifine mystruct
    struct mystruct {
    int x;
    int y;
    int z,
    } coord;

    now since the x, y, and z values match the register width, the Databus
    width, you don't have to ( unpack) or (pack) anything,

    of the three methods here,

    the first one really helps the programmer, and saves space, at the expense
    of clock cycles,

    the second method saves space, and saves clock cycles at the expense of the
    programmer,

    while the third method uses more space, but huals ass, and takes just as
    much time to code as the 1st method.

    I'm not going to suggest not using char, You would have to write a sh__ load
    of string proccessing code, ( "already been done").
    But you can logically order the information, and resize some information to
    give you the best of all 3 methods.

    I hope this clears up what I was trying to say the first post.

    I thought everyone could follow it ok. I was wrong.

    IF( I_hurt_anyones_feeling)
    {
    my_Oppologies();
    }
    else O_FN_WELL;

    Later,

    Dan
     
    DHOLLINGSWORTH2, Mar 9, 2005
    #15
  16. ccwork

    Richard Bos Guest

    "Mark F. Haigh" <> wrote:

    > Walter Roberson wrote:
    >
    > > If you re-examine what you are allowed to do with pointers, you will
    > > find that you are not allowed to compare pointers to different
    > > objects [even of the same type],

    >
    > Incorrect:
    >
    > 6.5.9 Equality operators


    > 6 Two pointers compare equal if and only if


    Equal, yes. You're allowed to compare pointers for equality. This is
    simply done even in segmented or type-separated memory by noting that
    two non-null pointers of different type need never compare equal at all:
    they point to different kinds of objects, therefore not to the same
    object; they are by definition not null; and if types are separated, an
    array of one type never follows an array of another type.
    If memory really were a gigantic array of ints, as DHOLLINGSWORTH2 seems
    to think, then you would be able to do a lot more. You could, for
    example, compare random pointers for order. That may be possible on many
    common systems, but the Standard doesn't guarantee it.

    Richard
     
    Richard Bos, Mar 9, 2005
    #16
  17. ----- Original Message -----
    From: "Richard Bos" <>
    Newsgroups: comp.lang.c
    Sent: Wednesday, March 09, 2005 4:01 AM
    Subject: Re: union with packed struct


    > If memory really were a gigantic array of ints, as DHOLLINGSWORTH2 seems
    > to think, then you would be able to do a lot more. You could, for


    if it wern't youd be wondering what a pointer is for. How to clear up the
    ambiguity and what not.

    if it weren't you would not be able to this:

    char * text = "Some bs text to prove a DA point";
    char text2[32];

    int * pitext = text;
    int * pitext2 = text2;

    for( int i = 0; i < (32/ sizeof( int)); i++)
    {
    pitext2 = pitext;
    }

    // which copies from one string to the next
    // by int's instead of by chars
    // 4 times faster on 32 bit machine,
    // and 8 times faster on a 64 bit machine

    MEM is also just an array of bits;
    also just an array of bytes;
    also just an array of short's;
    but where the i86 architecture is concerned
    it's most like an array of int's.

    I haven't seen a compiler one that shows any difference to that FACT.


    > common systems, but the Standard doesn't guarantee it.


    I'll give you that, my specialty is doing all the Dirty NON-STANDARD work
    you think can't get done.
     
    DHOLLINGSWORTH2, Mar 9, 2005
    #17
  18. DHOLLINGSWORTH2 wrote:
    > You can slice it by the bit, you can slice it by GiG.
    >
    > There is still only one address per Location!


    'Address' is not so easily defined. There may be 10,000 processes
    running on a box, each with 10,000 different ideas of what exists at
    virtual address 0x1234.

    Further, a pointer with the integer value of 42 may mean the 42nd byte
    of memory, the 42nd word, or the 42,000th quadword. It all depends on
    the type of the pointer.

    What we are concerned with here is the meaning the C standard gives to
    'address', and what is guaranteed, no matter what the platform
    involved.

    >
    > I have used microproccessors with RISC, with nonrisc, even some with

    a
    > PRogrammable micro code.
    >
    > And on every Computer, microproccessor, digital circuit, there is

    still only
    > one location for the specified address, I dont care how big or small

    a chunk
    > you look at. Or on what HW you look at.
    >


    Whoopdee doo. You're talking to people here that deal with and develop
    for these systems daily.

    > The computer will not change it's abilities to read what the Memory

    bus can
    > put out between members in a struct.
    > There is NO physical conection.
    >
    > You act like your bits can't possibly be what the HW was designed to
    > manipulate.
    >
    > Why would you build a 32 bit data bus and say that reading 4 chunks

    of 8
    > bits each were any faster than reading the whole 32.
    > would reading 32 chunks of 1 bit, be even faster?
    >


    You clearly don't understand what you're talking about. Who said
    anything about a 32 bit data bus? It could be a 1 bit data bus for all
    you know.

    >
    > IT doesn't matter, in memory, the BITS are stored in contiguous

    groups.
    >


    That's not even partially correct. There may be all kinds of holes in
    a physical or virtual memory map. The 'next' bit may be on your local
    DIMM 0 or in an undisclosed location across the Pacific in Kaz Khyleku
    and Dan Pop's underground lair of doom. So no, bits are not always
    stored contiguously, be it physically, virtually, or logically.

    Additionally, objects themselves can contain 'padding' bits, whose
    values are unspecified:

    6.2.6.2 Integer types

    1 For unsigned integer types other than unsigned char,
    the bits of the object representation shall be divided
    into two groups: value bits and padding bits (there need
    not be any of the latter).
    [...]
    The values of any padding bits are unspecified.


    > For example the 486 uses 32 bit registers, the actual indexing is

    done 8
    > bits per address. However reading 4 chars is slower than 1 dword.
    > Becuase you read 32 bits for each char read. FACT!
    >
    > even on your micropro with bitslicing architecture, lets say you have

    16
    > bits of data bus, but you only want to use 4 bits. OK you can, ITs

    still in
    > the middle of one huge array of integers. FACT! It's still

    contiguous.
    >
    > And every time you access those 4 bits they are in the same Physical
    > location as before.
    >


    No. Your claims run from the misleading to the blatantly wrong.

    >
    > I think you may have confused what I was saying with how I was saying

    it.
    >
    > Do you think we should optimize code that only utilized 1/8 of the

    register,
    > or 1/4 of the data bus, whats the point.
    > You have to get the code to run twice as fast to make up for only

    using 1/2
    > the registers, 1/2 data bus, etc.
    > Thats always going to be true. And that is my point.


    Nothing you have just said will always be true. 'Optimization' itself
    is even loosely defined, as it depends on the situation.

    Also, please stop top-posting, it's annoying.


    Mark F. Haigh
     
    Mark F. Haigh, Mar 9, 2005
    #18
  19. DHOLLINGSWORTH2 wrote:
    > ----- Original Message -----
    > From: "Richard Bos" <>
    > Newsgroups: comp.lang.c
    > Sent: Wednesday, March 09, 2005 4:01 AM
    > Subject: Re: union with packed struct
    >
    >
    > > If memory really were a gigantic array of ints, as DHOLLINGSWORTH2

    seems
    > > to think, then you would be able to do a lot more. You could, for

    >
    > if it wern't youd be wondering what a pointer is for. How to clear

    up the
    > ambiguity and what not.
    >
    > if it weren't you would not be able to this:
    >
    > char * text = "Some bs text to prove a DA point";
    > char text2[32];
    >
    > int * pitext = text;
    > int * pitext2 = text2;
    >
    > for( int i = 0; i < (32/ sizeof( int)); i++)
    > {
    > pitext2 = pitext;
    > }


    No. You presume that &text[0] and &text2[0] are aligned properly for
    int access. This code could generate an alignment trap on the ARM
    processor box here on my desk.

    Not to mention that since you're using signed ints to copy the data,
    you could inadvertently cause an int to be loaded with a trap
    representation.

    Simply put, you are not qualified to be giving advice to anyone.

    <snip>

    > I'll give you that, my specialty is doing all the Dirty NON-STANDARD

    work
    > you think can't get done.


    Maybe you can tell us where you work so we can all steer clear of your
    company's products.


    Mark F. Haigh
     
    Mark F. Haigh, Mar 9, 2005
    #19
  20. ccwork

    ccwork Guest

    DHOLLINGSWORTH2 wrote:
    > no,


    No. What you said is: Keep in mind that a struct is just an int[],
    with mapping handles for the "Programmer". This is wrong:
    struct is not int[]. In other word, the offset of each struct member
    is not always a multiple of fixed value. Say,
    struct PACKED s
    {
    char a;
    int b;
    char c;
    int d;
    } x;
    So &(x.a) has offset 0 to &x, &(x.b) has offset 1 to &x, &(x.c) has
    offset 5 to &x and &(x.d) has offset 6 to &x. This is DIFFERENT from
    array.
    Obviously you gave a wrong example. And then you talked about data
    bus, memory model, 64-bit, etc. All of them are dependent and not
    standard C.

    > what I mean is that
    >
    > char * s ="Some text in ram!";
    >
    > the text "Some text in ram!" is actually stored in ram.
    > in contiguous chunks.
    >
    > you could say char s[]; represents an area in ram at s,
    >
    > I'M Saying that all of your ram can be looked at like
    > int []; instead of some char [], some word[]; etc.
    >
    > When you store the data in a form the Hardware naturally proccessess

    you are
    > going to save more clock cycles than you will pull out optimizing

    your code
    > by hand.
    >
    > Simple put, Streamlining your code, does more for you than

    optimizing. When
    > you use data structures that are not in anyway equivelant to the

    native
    > operation of your HW.
    >
    > char s[] = "Some text in Ram";
    >
    > as an int[]; is the same exact pattern in memory;
    >
    > as a programmer you would have to unpack the integer to get the

    individual
    > char values. when you use char []; the packing, and unpacking is

    done
    > "behind the scene".
    >
    > Lets say you have a struct :
    >
    > struct myStruct {
    > short x;
    > short y;
    > short z;
    > } coord;
    >
    > accessing coord.x means you are loading an intire register with int,

    and
    > croping it to obtain the short portion.
    >
    > in effect, incrementing x, y, z means you have loaded at least one of

    these
    > twice, once you through it out, and the second time, you through the

    rest
    > out.
    >
    > on a 64 bit machine, Which reads and writes 64 bits at a time, you

    would
    > read in each value, 16 bits, once, and get the other 48 bits with it,

    crop
    > it ( unpack) , increment it, add the 48 bits back in,( pack it ),

    then save
    > it back to ram.
    >
    > you could read all 3 shorts at once by alligning your structure on a

    64 bit
    > boundary, and inc each one in one clock cycle, and similarly in one

    write
    > cycle store all three values back.
    > or
    > (this was my original statement)
    > you can redifine mystruct
    > struct mystruct {
    > int x;
    > int y;
    > int z,
    > } coord;
    >
    > now since the x, y, and z values match the register width, the

    Databus
    > width, you don't have to ( unpack) or (pack) anything,
    >
    > of the three methods here,
    >
    > the first one really helps the programmer, and saves space, at the

    expense
    > of clock cycles,
    >
    > the second method saves space, and saves clock cycles at the expense

    of the
    > programmer,
    >
    > while the third method uses more space, but huals ass, and takes just

    as
    > much time to code as the 1st method.
    >
    > I'm not going to suggest not using char, You would have to write a

    sh__ load
    > of string proccessing code, ( "already been done").
    > But you can logically order the information, and resize some

    information to
    > give you the best of all 3 methods.
    >
    > I hope this clears up what I was trying to say the first post.
    >
    > I thought everyone could follow it ok. I was wrong.
    >
    > IF( I_hurt_anyones_feeling)
    > {
    > my_Oppologies();
    > }
    > else O_FN_WELL;
    >
    > Later,
    >
    > Dan
     
    ccwork, Mar 9, 2005
    #20
    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. umberto
    Replies:
    4
    Views:
    574
    umberto
    Oct 24, 2003
  2. Chris
    Replies:
    6
    Views:
    510
    Chris Uppal
    Nov 7, 2004
  3. Matt Garman
    Replies:
    1
    Views:
    671
    Matt Garman
    Apr 25, 2004
  4. Chris Fogelklou
    Replies:
    36
    Views:
    1,393
    Chris Fogelklou
    Apr 20, 2004
  5. Peter Dunker

    union in struct without union name

    Peter Dunker, Apr 26, 2004, in forum: C Programming
    Replies:
    2
    Views:
    877
    Chris Torek
    Apr 26, 2004
Loading...

Share This Page