Four variables share one string?

Discussion in 'C++' started by Nephi Immortal, Dec 24, 2011.

  1. Is there a way how to create ONE four bytes in memory storage and
    four variables can access one str directly? I can do that without
    static const and C++ Compiler will be able to compile without any
    problem, but static is disallowed in union.
    I do not want to use pointer variable to str because I prefer “direct
    memory” variable instead of “indirect memory” variable.

    union
    {
    static const char str[ 5 ] = “ABCD”;
    struct Letter
    {
    static const char a;
    static const char b;
    static const char c;
    static const char d;
    } letter;
    };

    char A = letter.a; // read A from str and put it in A variable
    char B = letter.b; // read A from str and put it in B variable
    char C = letter.c; // read A from str and put it in C variable
    char D = letter.d; // read A from str and put it in D variable
    Nephi Immortal, Dec 24, 2011
    #1
    1. Advertising

  2. On 12/24/2011 5:54 PM, Nephi Immortal wrote:
    > Is there a way how to create ONE four bytes in memory storage and
    > four variables can access one str directly? I can do that without
    > static const and C++ Compiler will be able to compile without any
    > problem, but static is disallowed in union.
    > I do not want to use pointer variable to str because I prefer “direct
    > memory†variable instead of “indirect memory†variable.
    >
    > union
    > {
    > static const char str[ 5 ] = “ABCDâ€;
    > struct Letter
    > {
    > static const char a;
    > static const char b;
    > static const char c;
    > static const char d;
    > } letter;
    > };
    >
    > char A = letter.a; // read A from str and put it in A variable
    > char B = letter.b; // read A from str and put it in B variable
    > char C = letter.c; // read A from str and put it in C variable
    > char D = letter.d; // read A from str and put it in D variable


    You could try

    struct Foo {
    static const char str[5]; // initialization has to be outside
    static const char &a;
    static const char &b;
    static const char &c;
    static const char &d;
    };

    const char Foo::str[] = { "ABCD" };
    const char &Foo::a = Foo::str[0];
    const char &Foo::b = Foo::str[1];
    const char &Foo::c = Foo::str[2];
    const char &Foo::d = Foo::str[3];

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 24, 2011
    #2
    1. Advertising

  3. On Dec 24, 5:21 pm, Victor Bazarov <> wrote:
    > On 12/24/2011 5:54 PM, Nephi Immortal wrote:
    >
    >
    >
    >
    >
    > >    Is there a way how to create ONE four bytes in memory storage and
    > > four variables can access one str directly?  I can do that without
    > > static const and C++ Compiler will be able to compile without any
    > > problem, but static is disallowed in union.
    > >    I do not want to use pointer variable to str because I prefer “direct
    > > memory” variable instead of “indirect memory” variable.

    >
    > > union
    > > {
    > >    static const char str[ 5 ] = “ABCD”;
    > >    struct Letter
    > >    {
    > >            static const char a;
    > >            static const char b;
    > >            static const char c;
    > >            static const char d;
    > >    } letter;
    > > };

    >
    > >    char A = letter.a; // read A from str and put it in A variable
    > >    char B = letter.b; // read A from str and put it in B variable
    > >    char C = letter.c; // read A from str and put it in C variable
    > >    char D = letter.d; // read A from str and put it in D variable

    >
    > You could try
    >
    >     struct Foo {
    >         static const char str[5]; // initialization has to be outside
    >         static const char &a;
    >         static const char &b;
    >         static const char &c;
    >         static const char &d;
    >     };
    >
    >     const char Foo::str[] = { "ABCD" };
    >     const char &Foo::a = Foo::str[0];
    >     const char &Foo::b = Foo::str[1];
    >     const char &Foo::c = Foo::str[2];
    >     const char &Foo::d = Foo::str[3];


    str variable is direct memory address. It requires only one x86
    instruction. If you choose to use reference or pointer, both
    reference and pointer are just the same because it is indirect memory
    address and requires two x86 instructions.
    Unfortunately, four reference variables require additional 16 bytes
    while str array holds only four bytes plus one byte as null
    terminator.
    union is only the option to allow one four bytes while five variables
    share one memory space.
    If you only use one variable as str[ x ], you actually don’t know
    what individual character represents is for?

    char a = str[ 0 ]; // don’t know what str[ 0 ] is
    char b = str[ 1 ]; // don’t know what str[ 1 ] is

    With union, you know what it is:

    char a = letter_A;
    char b = letter_B;

    Perhaps enum is helpful.

    enum
    {
    letter_A,
    letter_B,
    letter_C,
    letter_D
    };

    char a = str[ letter_A ]; // know what str[ 0 ] is
    char b = str[ letter_B ]; // know what str[ 1 ] is

    enum has four constants and require additional 16 bytes.
    Do you have idea if there is another way how to overcome union to
    accept const instead of static const?

    Keep in touch – Merry Christmas!! Smile…
    Nephi Immortal, Dec 25, 2011
    #3
  4. Nephi Immortal <> writes:

    > enum has four constants and require additional 16 bytes.


    Usually not true. In typical implementations of C++ (and C),
    if you compile

    enum { zero, one, two, three };
    int f(const int p[])
    {
    return p[two] - p[three];
    }

    the generated code and data are the same as if you had compiled

    int f(const int p[])
    {
    return p[2] - p[3];
    }

    i.e. the enum type does not take up space in the executable
    program. It does take up space in debug information, symbol
    tables, and such; but if you are compiling for a device with so
    little memory that you need to worry about 16 bytes, then you
    probably will not install those things into the device anyway.

    > Do you have idea if there is another way how to overcome union to
    > accept const instead of static const?


    If the union does not need to be anonymous, you can do this:

    static const union
    {
    char str[ 5 ];
    struct Letter
    {
    char a;
    char b;
    char c;
    char d;
    } letter;
    } u = {"ABCD"};

    int main()
    {
    char A = u.letter.a; // read 'A' from str and put it in A variable
    char B = u.letter.b; // read 'B' from str and put it in B variable
    char C = u.letter.c; // read 'C' from str and put it in C variable
    char D = u.letter.d; // read 'D' from str and put it in D variable
    }
    Kalle Olavi Niemitalo, Dec 25, 2011
    #4
  5. On 12/25/2011 7:20 AM, Kalle Olavi Niemitalo wrote:
    > Nephi Immortal<> writes:
    >
    >> enum has four constants and require additional 16 bytes.

    >
    > Usually not true. In typical implementations of C++ (and C),
    > if you compile
    >
    > enum { zero, one, two, three };
    > int f(const int p[])
    > {
    > return p[two] - p[three];
    > }
    >
    > the generated code and data are the same as if you had compiled
    >
    > int f(const int p[])
    > {
    > return p[2] - p[3];
    > }
    >
    > i.e. the enum type does not take up space in the executable
    > program. It does take up space in debug information, symbol
    > tables, and such; but if you are compiling for a device with so
    > little memory that you need to worry about 16 bytes, then you
    > probably will not install those things into the device anyway.
    >
    >> Do you have idea if there is another way how to overcome union to
    >> accept const instead of static const?

    >
    > If the union does not need to be anonymous, you can do this:
    >
    > static const union
    > {
    > char str[ 5 ];
    > struct Letter
    > {
    > char a;
    > char b;
    > char c;
    > char d;
    > } letter;
    > } u = {"ABCD"};
    >
    > int main()
    > {
    > char A = u.letter.a; // read 'A' from str and put it in A variable
    > char B = u.letter.b; // read 'B' from str and put it in B variable
    > char C = u.letter.c; // read 'C' from str and put it in C variable
    > char D = u.letter.d; // read 'D' from str and put it in D variable
    > }


    Strictly speaking, the point of unions is to share the memory, the
    ability to store something, BUT NOT the value of it. The 2003 Standard
    still allowed to read only the value that was put in the union, but
    never write one part and read another. That actually has undefined
    behavior. I don't know whether that was relaxed in C++11.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 25, 2011
    #5
  6. On 25 déc, 14:54, Victor Bazarov <> wrote:
    > On 12/25/2011 7:20 AM, Kalle Olavi Niemitalo wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > Nephi Immortal<>  writes:

    >
    > >>        enum has four constants and require additional 16 bytes..

    >
    > > Usually not true.  In typical implementations of C++ (and C),
    > > if you compile

    >
    > > enum { zero, one, two, three };
    > > int f(const int p[])
    > > {
    > >          return p[two] - p[three];
    > > }

    >
    > > the generated code and data are the same as if you had compiled

    >
    > > int f(const int p[])
    > > {
    > >          return p[2] - p[3];
    > > }

    >
    > > i.e. the enum type does not take up space in the executable
    > > program.  It does take up space in debug information, symbol
    > > tables, and such; but if you are compiling for a device with so
    > > little memory that you need to worry about 16 bytes, then you
    > > probably will not install those things into the device anyway.

    >
    > >>        Do you have idea if there is another way how to overcome union to
    > >> accept const instead of static const?

    >
    > > If the union does not need to be anonymous, you can do this:

    >
    > > static const union
    > > {
    > >    char str[ 5 ];
    > >    struct Letter
    > >    {
    > >            char a;
    > >            char b;
    > >            char c;
    > >            char d;
    > >    } letter;
    > > } u = {"ABCD"};

    >
    > > int main()
    > > {
    > >    char A = u.letter.a; // read 'A' from str and put it in A variable
    > >    char B = u.letter.b; // read 'B' from str and put it in B variable
    > >    char C = u.letter.c; // read 'C' from str and put it in C variable
    > >    char D = u.letter.d; // read 'D' from str and put it in D variable
    > > }

    >
    > Strictly speaking, the point of unions is to share the memory, the
    > ability to store something, BUT NOT the value of it.  The 2003 Standard
    > still allowed to read only the value that was put in the union, but
    > never write one part and read another.  That actually has undefined
    > behavior.  I don't know whether that was relaxed in C++11.


    Actually, you can if they are POD and have a common initial sequence
    (see §9.5/1).

    Now, we could argue that in the example 'str' and 'Letter' have a
    common initial sequence of four char. Perhaps strictly speaking not
    layout compatible but they are actually both aggregates of char.

    --
    Michael
    Michael DOUBEZ, Dec 26, 2011
    #6
  7. On Dec 25, 7:54 am, Victor Bazarov <> wrote:
    > On 12/25/2011 7:20 AM, Kalle Olavi Niemitalo wrote:
    >
    >
    >
    >
    >
    > > Nephi Immortal<>  writes:

    >
    > >>        enum has four constants and require additional 16 bytes..

    >
    > > Usually not true.  In typical implementations of C++ (and C),
    > > if you compile

    >
    > > enum { zero, one, two, three };
    > > int f(const int p[])
    > > {
    > >          return p[two] - p[three];
    > > }

    >
    > > the generated code and data are the same as if you had compiled

    >
    > > int f(const int p[])
    > > {
    > >          return p[2] - p[3];
    > > }

    >
    > > i.e. the enum type does not take up space in the executable
    > > program.  It does take up space in debug information, symbol
    > > tables, and such; but if you are compiling for a device with so
    > > little memory that you need to worry about 16 bytes, then you
    > > probably will not install those things into the device anyway.

    >
    > >>        Do you have idea if there is another way how to overcome union to
    > >> accept const instead of static const?

    >
    > > If the union does not need to be anonymous, you can do this:

    >
    > > static const union
    > > {
    > >    char str[ 5 ];
    > >    struct Letter
    > >    {
    > >            char a;
    > >            char b;
    > >            char c;
    > >            char d;
    > >    } letter;
    > > } u = {"ABCD"};

    >
    > > int main()
    > > {
    > >    char A = u.letter.a; // read 'A' from str and put it in A variable
    > >    char B = u.letter.b; // read 'B' from str and put it in B variable
    > >    char C = u.letter.c; // read 'C' from str and put it in C variable
    > >    char D = u.letter.d; // read 'D' from str and put it in D variable
    > > }

    >
    > Strictly speaking, the point of unions is to share the memory, the
    > ability to store something, BUT NOT the value of it.  The 2003 Standard
    > still allowed to read only the value that was put in the union, but
    > never write one part and read another.  That actually has undefined
    > behavior.  I don't know whether that was relaxed in C++11.


    However, all five variables share the same memory address as long as
    you can do read only AND read/write only. Think of two pointers
    below.

    char arraySector[ 4096 ];

    char* beginArraySector = &arraySector[ 0 ];
    char* endArraySector = &arraySector[ 4096 - 1 ];

    const char* cBeginArraySector = &arraySector[ 0 ];
    const char* cEndArraySector = &arraySector[ 4096 - 1 ];

    *( beginArraySector + 100 ) = ‘A’; // read/write only
    *( endArraySector - 1000 ) = ‘Z’; // read/write only

    char A = *( cBeginArraySector + 100 ); // read only
    char B = *( cEndArraySector - 1000 ); // read only

    I choose to use union instead of pointer and/or reference because I
    want to use direct memory and not indirect memory. Another folk
    already answered the question. I am satisfied.
    Nephi Immortal, Dec 26, 2011
    #7
  8. On 12/26/2011 10:50 AM, Nephi Immortal wrote:
    > On Dec 25, 7:54 am, Victor Bazarov<> wrote:
    >> On 12/25/2011 7:20 AM, Kalle Olavi Niemitalo wrote:
    >>
    >>
    >>
    >>
    >>
    >>> Nephi Immortal<> writes:

    >>
    >>>> enum has four constants and require additional 16 bytes.

    >>
    >>> Usually not true. In typical implementations of C++ (and C),
    >>> if you compile

    >>
    >>> enum { zero, one, two, three };
    >>> int f(const int p[])
    >>> {
    >>> return p[two] - p[three];
    >>> }

    >>
    >>> the generated code and data are the same as if you had compiled

    >>
    >>> int f(const int p[])
    >>> {
    >>> return p[2] - p[3];
    >>> }

    >>
    >>> i.e. the enum type does not take up space in the executable
    >>> program. It does take up space in debug information, symbol
    >>> tables, and such; but if you are compiling for a device with so
    >>> little memory that you need to worry about 16 bytes, then you
    >>> probably will not install those things into the device anyway.

    >>
    >>>> Do you have idea if there is another way how to overcome union to
    >>>> accept const instead of static const?

    >>
    >>> If the union does not need to be anonymous, you can do this:

    >>
    >>> static const union
    >>> {
    >>> char str[ 5 ];
    >>> struct Letter
    >>> {
    >>> char a;
    >>> char b;
    >>> char c;
    >>> char d;
    >>> } letter;
    >>> } u = {"ABCD"};

    >>
    >>> int main()
    >>> {
    >>> char A = u.letter.a; // read 'A' from str and put it in A variable
    >>> char B = u.letter.b; // read 'B' from str and put it in B variable
    >>> char C = u.letter.c; // read 'C' from str and put it in C variable
    >>> char D = u.letter.d; // read 'D' from str and put it in D variable
    >>> }

    >>
    >> Strictly speaking, the point of unions is to share the memory, the
    >> ability to store something, BUT NOT the value of it. The 2003 Standard
    >> still allowed to read only the value that was put in the union, but
    >> never write one part and read another. That actually has undefined
    >> behavior. I don't know whether that was relaxed in C++11.

    >
    > However, all five variables share the same memory address as long as
    > you can do read only AND read/write only.[..]


    If you write one member of the union, any attempt to read another member
    of the union has undefined behavior, unless they are both POD and share
    the same layout. See Michael's post explaining that you *might* still
    be OK if we somehow consider that four 'char' members of your 'struct
    Letter' have the _same layout_ as the five-element array or char.

    Whatever tricks you want to play with addresses is system-, compiler-
    and platform-specific, and any use of it is at the risk of the one who
    uses it, the *Standard* does not specify any behavior for it. That's all.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 26, 2011
    #8
    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. Manish
    Replies:
    1
    Views:
    632
    Steve C. Orr [MVP, MCSD]
    Nov 17, 2003
  2. -
    Replies:
    4
    Views:
    328
    Owen Jacobson
    Jul 10, 2005
  3. Saraswati lakki
    Replies:
    0
    Views:
    1,287
    Saraswati lakki
    Jan 6, 2012
  4. Jack
    Replies:
    2
    Views:
    201
  5. Eric Wong
    Replies:
    0
    Views:
    191
    Eric Wong
    Feb 13, 2010
Loading...

Share This Page