Index a #define string

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Christopher Benson-Manica

    #16
    Re: Index a #define string

    Ioannis Vranos <ivr@guesswh.at .emails.ru> spoke thus:
    [color=blue]
    > You are wrong. static variables inside a function scope are still created in
    > the stack.[/color]

    Assuming the implementation uses a stack.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cybers pace.org | don't, I need to know. Flames welcome.

    Comment

    • David Harmon

      #17
      Re: Index a #define string

      On Fri, 16 Apr 2004 20:46:22 +0300 in comp.lang.c++, "Ioannis Vranos"
      <ivr@guesswh.at .emails.ru> wrote,[color=blue]
      >At first, i assumed the definition takes place in a local scope and not in
      >the global or a namespace scope.[/color]

      I assumed otherwise, since I have seen some huge number of such #define
      constants in C code, and a somewhat lesser number of const strings in
      C++ code, and the vast majority of them were near the top of the file
      before any functions, if not in headers included near the top of the
      file before any functions.
      [color=blue]
      >But except of that, where do you think global "non-static" variables are
      >created?[/color]

      I don't understand that. All globals have static lifetime, or they
      wouldn't be global. Show me the declaration of what you are talking
      about and I'll tell you where I think it's created.
      [color=blue][color=green]
      >> It could only be
      >> on the stack if it were written local to a function, in which case I
      >> would have written it
      >> static const char mystring[] = "ABC";[/color]
      >
      >There would be no point for this. The time cost for creating this thing is a
      >joke. :-) (Even the compiler may optimise it entirely out).[/color]

      No point for what? There is certainly a point for putting "static" on
      the declaration of that, at function scope, however small the cost of
      omitting it on a string that happens to be very short.
      [color=blue][color=green]
      >> Unfortunately, "static" means different things at function scope and at
      >> file scope.[/color]
      >
      >Yes, and instead of using static keyword in the global scope it is better to
      >use an anonymous namespace.[/color]

      That's irrelevant. I was not suggesting "static" at global scope, I was
      explaining why I did _not_ use "static" at global scope in the previous
      example. Besides, consts at file scope are "static" in that sense by
      default anyway. For purposes of this thread it matters not whether the
      globals are declared "static" or in a namespace, or neither. It only
      matters regarding the locals.
      [color=blue]
      >You are wrong. static variables inside a function scope are still created in
      >the stack.[/color]

      No, not this time. Static variables wouldn't be static if they were on
      the stack. If they were on the stack, where do you think their values
      would be preserved from one call of the function to the next?

      To illustrate, here is an compilable example:

      const char* const MYSTRING = "ABC";
      const char mystring[] = "ABC";
      int main()
      {
      const char * cptr;
      cptr = mystring; // line 6
      cptr = MYSTRING; // line 7
      static const char mystring[] = "ABC";
      cptr = mystring; // line 9
      static const char* const MYSTRING = "ABC";
      cptr = MYSTRING; // line 11
      }

      I compiled that with MSVC 6.0 with default no optimization options (for
      most straightforward translation) and /Fa for assembly listing output.
      Here is the generated initialized data. You will notice the extra DD
      storage for the two pointers, and that both of the "static" local
      variables with the mangled names are in compile-time initialized
      constant memory, not on the stack.

      CONST SEGMENT
      _MYSTRING DD FLAT:$SG265
      _mystring DB 'ABC', 00H
      _?mystring@?1?? main@@9@4QBDB DB 'ABC', 00H
      _?MYSTRING@?1?? main@@9@4QBDB DD FLAT:$SG275
      CONST ENDS
      _DATA SEGMENT
      $SG265 DB 'ABC', 00H
      $SG275 DB 'ABC', 00H
      _DATA ENDS

      Now here is the MSVC generated code from the body of main(). Please
      notice that the only variable on the stack is the non-static "cptr".
      At no time does the code copy the characters "ABC\0" to the stack from
      somewhere else. Also, there is the extra instruction required for
      indirection in each of the pointer versions.

      ; Line 6
      mov DWORD PTR _cptr$[ebp], OFFSET FLAT:_mystring
      ; Line 7
      mov eax, DWORD PTR _MYSTRING
      mov DWORD PTR _cptr$[ebp], eax
      ; Line 9
      mov DWORD PTR _cptr$[ebp], OFFSET FLAT:_?mystring @?1??main@@9@4Q BDB
      ; Line 11
      mov ecx, DWORD PTR _?MYSTRING@?1?? main@@9@4QBDB
      mov DWORD PTR _cptr$[ebp], ecx

      So you see, it is all exactly as I have told you.

      Comment

      • Ioannis Vranos

        #18
        Re: Index a #define string

        "David Harmon" <source@netcom. com> wrote in message
        news:4094284f.5 4313113@news.we st.earthlink.ne t...[color=blue]
        > On Fri, 16 Apr 2004 20:46:22 +0300 in comp.lang.c++, "Ioannis Vranos"
        > <ivr@guesswh.at .emails.ru> wrote,[color=green]
        > >At first, i assumed the definition takes place in a local scope and not[/color][/color]
        in[color=blue][color=green]
        > >the global or a namespace scope.[/color]
        >
        > I assumed otherwise, since I have seen some huge number of such #define
        > constants in C code, and a somewhat lesser number of const strings in
        > C++ code, and the vast majority of them were near the top of the file
        > before any functions, if not in headers included near the top of the
        > file before any functions.[/color]


        The subject is a bit confused. In the case of macros, it doesn't count where
        the macro is defined but where it is used, so since it was substituted
        inside a function (turning MYSTRING[0] to "ABC"[0] before compilation takes
        place), i considered it local. On the other hand he could place my
        suggestions in a header file in the place of the macro definition, but it
        doesn't matter anyway.


        [color=blue][color=green][color=darkred]
        > >> static const char mystring[] = "ABC";[/color]
        > >
        > >There would be no point for this. The time cost for creating this thing[/color][/color]
        is a[color=blue][color=green]
        > >joke. :-) (Even the compiler may optimise it entirely out).[/color]
        >
        > No point for what? There is certainly a point for putting "static" on
        > the declaration of that, at function scope, however small the cost of
        > omitting it on a string that happens to be very short.[/color]


        In this case, i wouldn't use an array myself but a const char * const, but
        never mind. If there isn't a specific advantage for making it static, why
        should one make it of static storage?


        [color=blue]
        > No, not this time. Static variables wouldn't be static if they were on
        > the stack. If they were on the stack, where do you think their values
        > would be preserved from one call of the function to the next?[/color]


        And where they get stored? As far as i know it is implementation-dependent
        but i think the usual is stack.


        [color=blue]
        >
        > To illustrate, here is an compilable example:
        >
        > const char* const MYSTRING = "ABC";
        > const char mystring[] = "ABC";
        > int main()
        > {
        > const char * cptr;
        > cptr = mystring; // line 6
        > cptr = MYSTRING; // line 7
        > static const char mystring[] = "ABC";
        > cptr = mystring; // line 9
        > static const char* const MYSTRING = "ABC";
        > cptr = MYSTRING; // line 11
        > }
        >
        > I compiled that with MSVC 6.0 with default no optimization options (for
        > most straightforward translation) and /Fa for assembly listing output.
        > Here is the generated initialized data. You will notice the extra DD
        > storage for the two pointers, and that both of the "static" local
        > variables with the mangled names are in compile-time initialized
        > constant memory, not on the stack.
        >
        > CONST SEGMENT
        > _MYSTRING DD FLAT:$SG265
        > _mystring DB 'ABC', 00H
        > _?mystring@?1?? main@@9@4QBDB DB 'ABC', 00H
        > _?MYSTRING@?1?? main@@9@4QBDB DD FLAT:$SG275
        > CONST ENDS
        > _DATA SEGMENT
        > $SG265 DB 'ABC', 00H
        > $SG275 DB 'ABC', 00H
        > _DATA ENDS[/color]


        I see a DD and a DB. But i do not know much of assembly, only very basic
        theoretic, that we fetch data from memory to registers and vice versa,
        e.t.c..

        So you mean that it is in a memory area reserved by the implementation. I
        can agree with that. The static storage space is implementation defined but
        i thought that the usual is stack (at the beginning of it).

        [color=blue]
        >
        > Now here is the MSVC generated code from the body of main(). Please
        > notice that the only variable on the stack is the non-static "cptr".
        > At no time does the code copy the characters "ABC\0" to the stack from
        > somewhere else.[/color]


        You mean that the compiler optimises it out. I can agree with that, but
        there is no guarantee that it will happen with all compilers, even with
        different versions of the same compiler. The overall implementation details
        we are discussing here are implementation-dependent. What i said is that if
        we define a built in array like this as auto, there is no real performance
        gain in most platforms. I think we should define a built in array to have
        static storage only when we see actual benefit from it. In the
        squeeze-every-cycle attitute (that i also had few years ago), you can gain 1
        cycle or two after subsequent function calls with that char array, but in my
        1,000,000 Hz CPU (and i bet you have a faster one) it will not be noticed,
        especially when the system idle process of windows takes 95% of the CPU time
        in the usual workload.

        I consider the use of static only for some object whose creation/destruction
        introduces significant time cost. Now if someone likes to optimise the
        run-time of creation/destruction of some chars, it is fine with me. :-)






        Ioannis Vranos

        Comment

        • Andrey Tarasevich

          #19
          Re: Index a #define string

          Christopher Benson-Manica wrote:[color=blue]
          > ...[color=green][color=darkred]
          >>>const char* const MYSTRING = "ABC";[/color][/color]
          >[color=green]
          >> const char mystring[] = "ABC";[/color]
          >
          > Are there any situations where the behavior of these two constructs
          > differs?[/color]

          Technically, yes. Remember that, firstly, string literal is an object
          with static storage duration in C++. It has no name but it has its own
          address in storage. And secondly, the implementation is allowed to merge
          identical literals. The consequence of this is that in the following code

          const char* const MYSTRING1 = "ABC";
          const char* const MYSTRING2 = "ABC";

          it is quite possible that both pointers will hold the same value
          (depends on implementation) .

          However, if you do it this way

          const char MYSTRING1[] = "ABC";
          const char MYSTRING2[] = "ABC";

          you can be sure that 'MYSTRING1' and 'MYSTRING2' are two different
          objects and values of '&MYSTRING1' and '&MYSTRING2' are guaranteed to be
          different.

          In most cases this behavior makes no difference in the actual program.
          But in some cases it could.

          --
          Best regards,
          Andrey Tarasevich

          Comment

          • Jack Klein

            #20
            Re: Index a #define string

            On Fri, 16 Apr 2004 23:46:01 +0300, "Ioannis Vranos"
            <ivr@guesswh.at .emails.ru> wrote in comp.lang.c++:
            [color=blue]
            > "David Harmon" <source@netcom. com> wrote in message
            > news:4094284f.5 4313113@news.we st.earthlink.ne t...[/color]

            [snip]
            [color=blue]
            > In this case, i wouldn't use an array myself but a const char * const, but
            > never mind. If there isn't a specific advantage for making it static, why
            > should one make it of static storage?
            >
            >
            >[color=green]
            > > No, not this time. Static variables wouldn't be static if they were on
            > > the stack. If they were on the stack, where do you think their values
            > > would be preserved from one call of the function to the next?[/color]
            >
            >
            > And where they get stored? As far as i know it is implementation-dependent
            > but i think the usual is stack.[/color]

            Since you have no idea at all how hardware stacks are used in typical
            processors under typical C++ implementations , perhaps you shouldn't
            try to answer questions here by discussing them incorrectly.

            --
            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.l earn.c-c++

            Comment

            • Julie

              #21
              Re: Index a #define string

              David Harmon wrote:[color=blue]
              >
              > On Fri, 16 Apr 2004 16:05:00 +0000 (UTC) in comp.lang.c++, Christopher
              > Benson-Manica <ataru@nospam.c yberspace.org> wrote,[color=green]
              > >Ioannis Vranos <ivr@guesswh.at .emails.ru> spoke thus:
              > >[color=darkred]
              > >> Avoid macros completely.[/color]
              > >
              > >Not all macros are evil.[/color]
              >
              > Example?[/color]

              #define NULL 0

              #define offsetof(s,m) (size_t)&(((s *)0)->m)

              Comment

              • Ioannis Vranos

                #22
                Re: Index a #define string

                "Julie" <julie@nospam.c om> wrote in message
                news:40814FCC.6 EEA51FC@nospam. com...[color=blue]
                >[/color]

                And some nicest alternatives:
                [color=blue]
                > #define NULL 0[/color]


                const int NULL=0;

                [color=blue]
                > #define offsetof(s,m) (size_t)&(((s *)0)->m)[/color]


                That appears to not work. You cast 0 to a struct/class pointer of s *, you
                dereference that null pointer it to access a data member m which is illegal,
                and then you get its address and cast it to size_t.






                Ioannis Vranos

                Comment

                • Julie

                  #23
                  Re: Index a #define string

                  Ioannis Vranos wrote:[color=blue]
                  > And some nicest alternatives:
                  >[color=green]
                  > > #define NULL 0[/color]
                  >
                  > const int NULL=0;[/color]

                  How about some justification as to why const is 'nicer' than #define, other
                  than rhetoric.
                  [color=blue][color=green]
                  > > #define offsetof(s,m) (size_t)&(((s *)0)->m)[/color]
                  >
                  > That appears to not work. You cast 0 to a struct/class pointer of s *, you
                  > dereference that null pointer it to access a data member m which is illegal,
                  > and then you get its address and cast it to size_t.[/color]

                  This is how it is implemented in my stddef.h -- the particulars are
                  implementation-defined, however the behavior is well-defined.

                  The previous poster wrote:[color=blue][color=green]
                  >> Not all macros are evil.[/color]
                  >
                  > Example?[/color]

                  I've provided two examples of macros that satisfy his question.

                  Comment

                  • Ioannis Vranos

                    #24
                    Re: Index a #define string


                    "Julie" <julie@nospam.c om> wrote in message
                    news:4081698B.E E90BB7B@nospam. com...[color=blue]
                    > Ioannis Vranos wrote:[color=green]
                    > > And some nicest alternatives:
                    > >[color=darkred]
                    > > > #define NULL 0[/color]
                    > >
                    > > const int NULL=0;[/color]
                    >
                    > How about some justification as to why const is 'nicer' than #define,[/color]
                    other[color=blue]
                    > than rhetoric.[/color]



                    The C++ Programming Language" 3rd Edition or Special Edition by Bjarne
                    Stroustrup (the creator of C++), page 88:


                    5.1.1 Zero

                    Zero (0) is an int. Because of standard conversions (§C.6.2.3), 0 can be
                    used as a constant of any integral (§4.1.1), floating point, pointer, or
                    pointer to member type. The type of zero will be determined by context. Zero
                    will typically (but not necessarily) be represented by the bit pattern
                    all-zeros of the appropriate size.

                    No object is allocated with the address 0. Consequently, 0 acts as a pointer
                    literal, indicating that a pointer doesn't refer to an object.

                    In C, it has been popular to define a macro NULL to represent the zero
                    pointer. Because of C++'s tighter type checking, the use of plain 0, rather
                    than any suggested NULL macro, leads to fewer problems. If you feel you must
                    define NULL, use

                    const int NULL = 0;

                    The const qualifier (§5.4) prevents accidental redefinition of NULL and
                    ensures that NULL can be used where a constant is required.



                    [color=blue][color=green][color=darkred]
                    > > > #define offsetof(s,m) (size_t)&(((s *)0)->m)[/color]
                    > >
                    > > That appears to not work. You cast 0 to a struct/class pointer of s *,[/color][/color]
                    you[color=blue][color=green]
                    > > dereference that null pointer it to access a data member m which is[/color][/color]
                    illegal,[color=blue][color=green]
                    > > and then you get its address and cast it to size_t.[/color]
                    >
                    > This is how it is implemented in my stddef.h -- the particulars are
                    > implementation-defined, however the behavior is well-defined.[/color]


                    That's a nice detail to quibble about.

                    As all know the C-style cast has also an equally dangerous equivalent.

                    If A, B two types:


                    (A)B is equivalent to A(B). A lame example:


                    char x=(char)5;

                    char x=char(5);



                    So the above thing does id equivalent to:

                    #define offsetof(s,m) (size_t)&((s *(0))->m)


                    It creates an s * pointer variable initialised to 0 and then accesses the m
                    data member. However the behaviour of both these is very system specific
                    *and* undefined.

                    [color=blue]
                    > The previous poster wrote:[color=green][color=darkred]
                    > >> Not all macros are evil.[/color]
                    > >
                    > > Example?[/color]
                    >
                    > I've provided two examples of macros that satisfy his question.[/color]



                    And yours above is not evil?







                    Ioannis Vranos

                    Comment

                    • Julie

                      #25
                      Re: Index a #define string

                      Ioannis Vranos wrote:[color=blue][color=green][color=darkred]
                      > > > > #define offsetof(s,m) (size_t)&(((s *)0)->m)
                      > > >
                      > > > That appears to not work. You cast 0 to a struct/class pointer of s *,[/color][/color]
                      > you[color=green][color=darkred]
                      > > > dereference that null pointer it to access a data member m which is[/color][/color]
                      > illegal,[color=green][color=darkred]
                      > > > and then you get its address and cast it to size_t.[/color]
                      > >
                      > > This is how it is implemented in my stddef.h -- the particulars are
                      > > implementation-defined, however the behavior is well-defined.[/color]
                      >
                      > That's a nice detail to quibble about.[/color]

                      Not quibbling about.

                      Take a look at the standard library regarding offsetof. The behavior is well
                      defined. How it is implemented, is implementation defined.

                      Forget about the actual implementation that I posted for a minute, and consider
                      the macro behavior. It is useful, well-defined, and a valuable component of
                      the standard library, and it is a macro.

                      I've answered the PP's question.
                      [color=blue]
                      > And yours above is not evil?[/color]

                      It isn't mine, but an example of a useful and beneficial macro.

                      The notion that "all macros are bad" is more dangerous than the potential
                      misuse of macros.

                      Chew on that for a while, once you get out of the box.

                      end.

                      Comment

                      • Kevin Goodsell

                        #26
                        Re: Index a #define string

                        Julie wrote:
                        [color=blue]
                        >
                        >[color=green][color=darkred]
                        >>>#define offsetof(s,m) (size_t)&(((s *)0)->m)[/color]
                        >>[/color]
                        >
                        > This is how it is implemented in my stddef.h -- the particulars are
                        > implementation-defined, however the behavior is well-defined.
                        >[/color]

                        You can't get well-defined out of implementation-defined. The best you
                        can hope for is more implementation defined.

                        However, in this case there is no implementation-defined behavior. It is
                        completely undefined.

                        -Kevin
                        --
                        My email address is valid, but changes periodically.
                        To contact me please use the address from a recent posting.

                        Comment

                        • Ioannis Vranos

                          #27
                          Re: Index a #define string

                          "Julie" <julie@nospam.c om> wrote in message
                          news:4081807E.F 08D6DBA@nospam. com...[color=blue]
                          >
                          > Not quibbling about.
                          >
                          > Take a look at the standard library regarding offsetof. The behavior is[/color]
                          well[color=blue]
                          > defined. How it is implemented, is implementation defined.
                          >
                          > Forget about the actual implementation that I posted for a minute, and[/color]
                          consider[color=blue]
                          > the macro behavior. It is useful, well-defined, and a valuable component[/color]
                          of[color=blue]
                          > the standard library, and it is a macro.[/color]


                          "Well-defined" and "implementa tion-defined" are different in ISO C++
                          terminology.

                          We can't discuss about implementation-defined programming. One could provide
                          a function, template function or some other interface and the implementation
                          in asm. When we say avoid the use of macros, is because the use of macros is
                          inherently dangerous, it may behave in an unexpected way, and bugs caused by
                          macro substitution of a macro defined in a header file which used in another
                          header file, which is used in our code are of the most difficult to trace.

                          C++ provides a superior alternative to macros (and void *s by the way) ,
                          templates. They are compile time checked and type safe.

                          [color=blue]
                          > The notion that "all macros are bad" is more dangerous than the potential
                          > misuse of macros.[/color]


                          Well it is apparent that we will stick to our own opinions.

                          [color=blue]
                          > Chew on that for a while, once you get out of the box.[/color]


                          I am not in the box, i am in the hug of my LCD monitor. :-)






                          Ioannis Vranos

                          Comment

                          • Julie

                            #28
                            Re: Index a #define string

                            Kevin Goodsell wrote:[color=blue]
                            >
                            > Julie wrote:
                            >[color=green]
                            > >
                            > >[color=darkred]
                            > >>>#define offsetof(s,m) (size_t)&(((s *)0)->m)
                            > >>[/color]
                            > >
                            > > This is how it is implemented in my stddef.h -- the particulars are
                            > > implementation-defined, however the behavior is well-defined.
                            > >[/color]
                            >
                            > You can't get well-defined out of implementation-defined. The best you
                            > can hope for is more implementation defined.
                            >
                            > However, in this case there is no implementation-defined behavior. It is
                            > completely undefined.[/color]

                            When you pick pieces out of context, you can make any argument that you want.

                            I said that the _particulars_ are implementation defined (meaning the
                            underlying implementation) , the _behavior_ is well defined.

                            Contrary to your belief, this is the case, and is entirely possible.

                            The previous poster requested an example of a 'non-evil' macro, and I provided
                            that.

                            As I said: The notion that "all macros are bad" is more dangerous than the
                            potential
                            misuse of macros.

                            Comment

                            • Kevin Goodsell

                              #29
                              Re: Index a #define string

                              Julie wrote:
                              [color=blue]
                              >
                              >
                              > When you pick pieces out of context, you can make any argument that you want.
                              >
                              > I said that the _particulars_ are implementation defined (meaning the
                              > underlying implementation) , the _behavior_ is well defined.[/color]

                              If you defined that macro yourself and used it, the behavior would NOT
                              be defined. You are free to use the library-supplied 'offsetof' macro,
                              and it will be well-defined, but that's not the same. An implementation
                              would be perfectly within its rights to (for example) crash on your
                              macro, even if it's identical to the standard library version.
                              [color=blue]
                              >
                              > Contrary to your belief, this is the case, and is entirely possible.[/color]

                              If you rely on implementation-defined behavior, you can't do better than
                              implementation-defined. But that's not particularly relevant, since
                              there was no implementation-defined behavior in the example.
                              [color=blue]
                              >
                              > The previous poster requested an example of a 'non-evil' macro, and I provided
                              > that.[/color]

                              'Evil' is a technical term in C++ circles. It doesn't mean "not to be
                              used under any circumstances". This is in the FAQ.

                              -Kevin
                              --
                              My email address is valid, but changes periodically.
                              To contact me please use the address from a recent posting.

                              Comment

                              • Julie

                                #30
                                Re: Index a #define string

                                Kevin Goodsell wrote:[color=blue]
                                > Julie wrote:
                                >[color=green]
                                > >
                                > >
                                > > When you pick pieces out of context, you can make any argument that you want.
                                > >
                                > > I said that the _particulars_ are implementation defined (meaning the
                                > > underlying implementation) , the _behavior_ is well defined.[/color]
                                >
                                > If you defined that macro yourself and used it, the behavior would NOT
                                > be defined. You are free to use the library-supplied 'offsetof' macro,
                                > and it will be well-defined, but that's not the same. An implementation
                                > would be perfectly within its rights to (for example) crash on your
                                > macro, even if it's identical to the standard library version.
                                >[color=green]
                                > >
                                > > Contrary to your belief, this is the case, and is entirely possible.[/color]
                                >
                                > If you rely on implementation-defined behavior, you can't do better than
                                > implementation-defined. But that's not particularly relevant, since
                                > there was no implementation-defined behavior in the example.
                                >[color=green]
                                > >
                                > > The previous poster requested an example of a 'non-evil' macro, and I provided
                                > > that.[/color]
                                >
                                > 'Evil' is a technical term in C++ circles. It doesn't mean "not to be
                                > used under any circumstances". This is in the FAQ.[/color]

                                So what is your point to all of your responses w/ respect to the previous
                                poster's question and my response???

                                Do you agree that the offsetof() macro is an example of a 'non-evil' macro or
                                not?

                                Comment

                                Working...