Data initialization (is this correct?)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • mathieu

    Data initialization (is this correct?)

    I would like to know if the following operation on s2 is legal or not.
    And if not what should I do instead (my data member are declared at the
    begining of the struct).
    I am pretty sure this is illegal, but I would like to avoid duplicating
    the logic that take place when initializing s1.

    Thanks for your help.
    Mathieu

    (*)
    #include <iostream>

    struct String
    {
    char Internal[4+1];
    void Print() {
    std::cout << Internal << std::endl;
    }
    };

    int main()
    {
    String s1 = {"019Y"}; // give compiler error if too large
    s1.Print();

    String s2;
    char array[] = "123D";
    s2 = reinterpret_cas t<String&>( array ); // is this legal
    s2.Print();
    return 0;
    }

  • Jerry Coffin

    #2
    Re: Data initialization (is this correct?)

    In article <1148696512.476 379.294630
    @i39g2000cwa.go oglegroups.com> ,
    mathieu.malater re@gmail.com says...

    [ ... ]
    [color=blue]
    > String s2;
    > char array[] = "123D";
    > s2 = reinterpret_cas t<String&>( array ); // is this legal[/color]

    That depends on what you mean by "legal". It doesn't give
    defined results, if that's what you mean.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.

    Comment

    • Luke Meyers

      #3
      Re: Data initialization (is this correct?)

      mathieu wrote:[color=blue]
      > I would like to know if the following operation on s2 is legal or not.
      > And if not what should I do instead (my data member are declared at the
      > begining of the struct).
      >
      > struct String
      > {
      > char Internal[4+1];
      > void Print() {
      > std::cout << Internal << std::endl;
      > }
      > };[/color]

      Kind of an odd struct -- is this something you're actually attempting
      to use, or a dumbed-down example? If the latter, fine. If the
      former... reconsider.
      [color=blue]
      > String s1 = {"019Y"}; // give compiler error if too large
      > s1.Print();
      >
      > String s2;
      > char array[] = "123D";
      > s2 = reinterpret_cas t<String&>( array ); // is this legal
      >
      > I am pretty sure this is illegal[/color]

      It's not technically illegal, but as with any use of reinterpret_cas t,
      there is no guarantee whatsoever as to what the result could be. It's
      100% implementation-defined and non-portable. Whatever you're trying
      to achieve, reinterpret_cas t is not the way.
      [color=blue]
      > but I would like to avoid duplicating
      > the logic that take place when initializing s1.[/color]

      Could you explain what you mean by this? There's not really any logic
      to speak of. Are you attempting to optimize for speed? Avoid code
      duplication? I don't think either is happening here.

      Luke

      Comment

      • Tomás

        #4
        Re: Data initialization (is this correct?)

        mathieu posted:

        [color=blue]
        > s2 = reinterpret_cas t<String&>( array ); // is this legal[/color]


        Yes, it's perfectly okay. I'll show you why. Firstly the Standard
        guarantees that the following is pefectly legal:

        struct Monkey {
        int array[10];
        };

        int main()
        {
        Monkey obj;

        int (&array)[10] =
        reinterpret_cas t<int (&)[10]>(obj);

        array[3] = 7;
        }


        Therefore the reverse must be true:


        struct Monkey {
        int array[10];
        };

        int main()
        {
        int array[10];

        Monkey &monkey =
        reinterpret_cas t<Monkey &>(array);

        monkey.array[3] = 7;
        }


        However, this only holds true for a POD. Here's the relevant passage from
        the Standard:

        9.2 p17: A pointer to a POD-struct, suitably converted using a
        reinterpret_cas t, points to its initial member (of if that member is a bit-
        field, then to the unit in which it resides) and vice versa."


        -Tomás

        Comment

        • Tomás

          #5
          Re: Data initialization (is this correct?)

          Jerry Coffin posted:
          [color=blue]
          > In article <1148696512.476 379.294630
          > @i39g2000cwa.go oglegroups.com> ,
          > mathieu.malater re@gmail.com says...
          >
          > [ ... ]
          >[color=green]
          >> String s2;
          >> char array[] = "123D";
          >> s2 = reinterpret_cas t<String&>( array ); // is this legal[/color]
          >
          > That depends on what you mean by "legal". It doesn't give
          > defined results, if that's what you mean.[/color]

          I disagree:

          9.2 p17: "A pointer to a POD-struct, suitably converted using a
          reinterpret_cas t, points to its initial member (of if that member is a bit-
          field, then to the unit in which it resides) and vice versa."

          I demonstrate exploitation of this feature elsewhere in the thread.

          -Tomás

          Comment

          • Jerry Coffin

            #6
            Re: Data initialization (is this correct?)

            In article <O50eg.9610$j7. 306562@news.ind igo.ie>,
            No.Email@Addres s says...

            [ ... ]
            [color=blue]
            > I disagree:
            >
            > 9.2 p17: "A pointer to a POD-struct, suitably converted using a
            > reinterpret_cas t, points to its initial member (of if that member is a bit-
            > field, then to the unit in which it resides) and vice versa."[/color]

            Rereading his definition of String, you're right. I
            apologize for the misinformation.

            --
            Later,
            Jerry.

            The universe is a figment of its own imagination.

            Comment

            • Roland Pibinger

              #7
              Re: Data initialization (is this correct?)

              On Sat, 27 May 2006 17:33:39 GMT, "Tomás" <No.Email@Addre ss> wrote:[color=blue]
              >mathieu posted:[color=green]
              >> s2 = reinterpret_cas t<String&>( array ); // is this legal[/color]
              >
              >Yes, it's perfectly okay. I'll show you why. Firstly the Standard
              >guarantees that the following is pefectly legal:
              >
              >struct Monkey {
              > int array[10];
              >};
              >
              >int main()
              >{
              > Monkey obj;
              >
              > int (&array)[10] =
              > reinterpret_cas t<int (&)[10]>(obj);
              >
              > array[3] = 7;
              >}
              >
              >
              >Therefore the reverse must be true:[/color]

              Nope. It probably 'works' in most cases but it's not correct C++, not
              even for PODs.

              Best wishes,
              Roland Pibinger

              Comment

              • Tomás

                #8
                Re: Data initialization (is this correct?)

                Roland Pibinger posted:

                [color=blue][color=green]
                >>Therefore the reverse must be true:[/color]
                >
                > Nope. It probably 'works' in most cases but it's not correct C++, not
                > even for PODs.[/color]


                Care to elaborate on that?


                Here's my logic:

                We start off with a simple POD as follows:

                struct Monkey { int array[10]; };


                We can convert a "Monkey*" to a "int (*)[10]", and we can subsequently
                use that pointer to access the array, i.e.:

                Monkey obj;

                int (*array)[10] = reinterpret_cas t<int (*)[10]>(&obj);

                (*array)[3] = 72;


                Why do you suppose that the opposite cannot be done:

                int array[10];

                Monkey *p_monkey =
                reinterpret_cas t<Monkey*>( &array );

                p_monkey->array[3] = 56;


                -Tomás

                Comment

                • Roland Pibinger

                  #9
                  Re: Data initialization (is this correct?)

                  On Sat, 27 May 2006 20:10:37 GMT, "Tomás" <No.Email@Addre ss> wrote:[color=blue]
                  >Roland Pibinger posted:
                  >[color=green][color=darkred]
                  >>>Therefore the reverse must be true:[/color]
                  >>
                  >> Nope. It probably 'works' in most cases but it's not correct C++, not
                  >> even for PODs.[/color]
                  >
                  >Care to elaborate on that?
                  >
                  >Here's my logic:
                  >We start off with a simple POD as follows:
                  >
                  > struct Monkey { int array[10]; };
                  >
                  >We can convert a "Monkey*" to a "int (*)[10]", and we can subsequently
                  >use that pointer to access the array, i.e.:[/color]

                  Ok
                  [color=blue]
                  > Monkey obj;
                  > int (*array)[10] = reinterpret_cas t<int (*)[10]>(&obj);
                  > (*array)[3] = 72;
                  >
                  >Why do you suppose that the opposite cannot be done:
                  >
                  > int array[10];
                  > Monkey *p_monkey =
                  > reinterpret_cas t<Monkey*>( &array );
                  > p_monkey->array[3] = 56;[/color]

                  You can only convert beetween a POD-stuct and its first data member
                  (and vice versa), not between an arbitrary 'int[10]' and 'struct
                  Monkey'. Monkey may be larger than array: sizeof (Monkey) >= sizeof
                  (array). Even alignment restricitions might be different (unlikely).

                  Best wishes,
                  Roland Pibinger

                  Comment

                  • Tomás

                    #10
                    Re: Data initialization (is this correct?)

                    Roland Pibinger posted:

                    [color=blue]
                    > You can only convert beetween a POD-stuct and its first data member
                    > (and vice versa), not between an arbitrary 'int[10]' and 'struct
                    > Monkey'. Monkey may be larger than array: sizeof (Monkey) >= sizeof
                    > (array).[/color]


                    I don't see how this would be a problem if we only use the resultant
                    Monkey* to access the struct's first member.

                    [color=blue]
                    > Even alignment restricitions might be different (unlikely).[/color]


                    Interesting point. I wonder if that's possible... ?


                    -Tomás

                    Comment

                    • mathieu

                      #11
                      Re: Data initialization (is this correct?)


                      Luke Meyers wrote:[color=blue]
                      > Kind of an odd struct -- is this something you're actually attempting
                      > to use, or a dumbed-down example? If the latter, fine. If the
                      > former... reconsider.
                      >[/color]

                      If you have nothing to do for memorial day here is the full source:

                      Comments welcome.
                      [color=blue]
                      > It's not technically illegal, but as with any use of reinterpret_cas t,
                      > there is no guarantee whatsoever as to what the result could be. It's
                      > 100% implementation-defined and non-portable. Whatever you're trying
                      > to achieve, reinterpret_cas t is not the way.[/color]

                      I simply need to fill in my structure at run time. The only other way I
                      can see is encapsulate all my templates (see link above) in one class
                      that would have a giant switch depending on the templates argument.
                      It's always the same problem interfacing templated code with run time
                      information.
                      [color=blue]
                      > Could you explain what you mean by this? There's not really any logic
                      > to speak of. Are you attempting to optimize for speed? Avoid code
                      > duplication? I don't think either is happening here.[/color]

                      I liked the fact the *compiler* was telling me something is wrong, such
                      as array is too big/small, not the right type. The idea was that I
                      could describe the whole DICOM standard, and then try to compile it, if
                      it does not compile the standard has a problem :)

                      Thanks for reading,
                      Mathieu

                      Comment

                      • mathieu

                        #12
                        Re: Data initialization (is this correct?)


                        Roland Pibinger wrote:
                        [color=blue]
                        > You can only convert beetween a POD-stuct and its first data member
                        > (and vice versa), not between an arbitrary 'int[10]' and 'struct
                        > Monkey'. Monkey may be larger than array: sizeof (Monkey) >= sizeof
                        > (array). Even alignment restricitions might be different (unlikely).[/color]

                        Oh I think I understand what you are saying. For instance:

                        struct Monkey {
                        int a;
                        int b;
                        };

                        the standard does not say anything on how to access Monkey.b. Is this
                        correct.
                        Therefore the standard does not say anything for an array, I can only
                        change the very first data member:

                        struct Monkey {
                        int array[10];
                        };

                        in this case: Monkey.array[0].

                        Thanks for your help,
                        Mathieu

                        Comment

                        • Tomás

                          #13
                          Re: Data initialization (is this correct?)

                          mathieu posted:

                          [color=blue]
                          > Therefore the standard does not say anything for an array, I can only
                          > change the very first data member:
                          >
                          > struct Monkey {
                          > int array[10];
                          > };[/color]


                          No, the entire array is counted as "one object". However it does have
                          "sub-objects"... just like how an "std::strin g" is thought of as one
                          object, even though it may have a few sub-objects. To take it to an
                          extreme:


                          struct Monkey {
                          int a[10];
                          double b;
                          void *p;
                          };

                          struct Ape {
                          Monkey monkey;
                          char k;
                          float s;
                          };

                          struct Lizard {
                          Ape ape;
                          char a;
                          char n;
                          };

                          int main()
                          {
                          Lizard obj;

                          int (&array)[10] = reinterpret_cas t<int (&)[10]>(obj);

                          array[3] = 37;
                          }


                          Or the inheritance way works aswell

                          struct Monkey { ...
                          struct Ape : Monkey { ...
                          struct Lizard : Ape { ...

                          Lizard obj;

                          int (&array)[10] = reinter...


                          Just so long as we're dealing with POD's.

                          -Tomás

                          -Tomás

                          Comment

                          • Luke Meyers

                            #14
                            Re: Data initialization (is this correct?)

                            mathieu wrote:[color=blue]
                            > If you have nothing to do for memorial day here is the full source:
                            > http://svn.sourceforge.net/viewcvs.c...?view=annotate
                            > Comments welcome.[/color]

                            That's funny... looking at that source, "comments welcome" is exactly
                            what I was thinking ;). Sorry, not enough time for guesswork -- though
                            if you'd care to point out the problematic section and explain what
                            you're trying to do in words, maybe you'll get the help you want.
                            [color=blue][color=green]
                            > > Whatever you're trying
                            > > to achieve, reinterpret_cas t is not the way.[/color]
                            >
                            > I simply need to fill in my structure at run time.[/color]

                            You mean like a constructor does?
                            [color=blue]
                            > The only other way I
                            > can see is encapsulate all my templates (see link above) in one class
                            > that would have a giant switch depending on the templates argument.[/color]

                            That sounds like a pretty ugly way to solve... some problem. What's
                            the problem you're trying to solve? All you've said is "fill in my
                            structure at run time," which sounds like a description of what
                            constructors do. What is it that you're trying to accomplish that you
                            feel you can't do with a constructor?
                            [color=blue]
                            > It's always the same problem interfacing templated code with run time
                            > information.[/color]

                            There are definitely complexities involved. I'm confused, though,
                            because your question had nothing to do with templates.
                            [color=blue][color=green]
                            > > Could you explain what you mean by this? There's not really any logic
                            > > to speak of. Are you attempting to optimize for speed? Avoid code
                            > > duplication? I don't think either is happening here.[/color]
                            >
                            > I liked the fact the *compiler* was telling me something is wrong, such
                            > as array is too big/small, not the right type. The idea was that I
                            > could describe the whole DICOM standard, and then try to compile it, if
                            > it does not compile the standard has a problem :)[/color]

                            That sounds very interesting -- what does it have to do with my
                            question? All I asked is what you meant about how you "would like to
                            avoid duplicating the logic that take [sic] place when initializing
                            s1."

                            Luke

                            Comment

                            • mathieu

                              #15
                              Re: Data initialization (is this correct?)

                              Luke Meyers wrote:[color=blue]
                              > mathieu wrote:[color=green]
                              > > If you have nothing to do for memorial day here is the full source:
                              > > http://svn.sourceforge.net/viewcvs.c...?view=annotate
                              > > Comments welcome.[/color]
                              >
                              > That's funny... looking at that source, "comments welcome" is exactly
                              > what I was thinking ;). Sorry, not enough time for guesswork -- though
                              > if you'd care to point out the problematic section and explain what
                              > you're trying to do in words, maybe you'll get the help you want.[/color]

                              Ok I'll try to summarize my problem with this simple one.
                              struct MyInt {
                              int Internal[4];
                              };
                              int main()
                              {
                              MyInt i = { 0,1,2,3 };
                              // MyInt i = { 0,1,2,3,4 }; // should throw an error
                              return 0;
                              }

                              Please describe a constructor that would do this exact job. I could not
                              figure out a way to throw an error when there are too many initializers
                              (see commented line).

                              Thanks
                              Mathieu

                              Comment

                              Working...