inline overload operation question

Discussion in 'C++' started by news.inode.at, Apr 11, 2008.

  1. Sorry for this stupid question, but i am lost.

    If i write an stringlib with += overload operators (no i do not, but my
    thing is much more complicated) , and i have to precalculate the strlen() --
    as seen in the example here
    How do i solve this ?
    struct myStr
    {
    private:
    unsigned len;
    unsigned size;
    char string[100];
    public:
    myStr():
    len(0),
    size(0)
    {
    string[0] = 0;
    }
    ~myStr() {}
    void AppendString(char * source)
    {
    printf("Adddynamic: %d\n",strlen(source));
    }
    void AppendString(const char * source,unsigned len)
    {
    printf("AddStatic: %d\n",len);
    }
    myStr operator+=(char * source)
    {
    printf("Add Dynamic Length\n");
    AppendString(source);
    return *this;
    }

    __forceinline myStr operator+=(const char * source)
    {
    printf("Add Static Length\n");
    // HELP !!!! --> why does he not inline the function and precalculate
    strlen() at compiletime ? is there a method ?
    like: templates or so ?

    AppendString(source,strlen(source));
    return *this;
    }

    };

    int _tmain(int argc, _TCHAR* argv[])
    {
    myStr test;
    test += "HHHHHHHHHHHHH"; //= 13 bytes = 0xd
    test.AppendString("HHHHHHHHHHHHH",strlen("HHHHHHHHHHHHH"));
    return 0;
    }



    thx

    franz
     
    news.inode.at, Apr 11, 2008
    #1
    1. Advertising

  2. news.inode.at wrote:
    > Sorry for this stupid question, but i am lost.
    >
    > If i write an stringlib with += overload operators (no i do not, but my
    > thing is much more complicated) , and i have to precalculate the strlen() --
    > as seen in the example here
    > How do i solve this ?
    > struct myStr
    > {
    > private:
    > unsigned len;
    > unsigned size;
    > char string[100];
    > public:
    > myStr():
    > len(0),
    > size(0)
    > {
    > string[0] = 0;
    > }
    > ~myStr() {}
    > void AppendString(char * source)
    > {
    > printf("Adddynamic: %d\n",strlen(source));
    > }
    > void AppendString(const char * source,unsigned len)
    > {
    > printf("AddStatic: %d\n",len);
    > }
    > myStr operator+=(char * source)
    > {
    > printf("Add Dynamic Length\n");
    > AppendString(source);
    > return *this;
    > }
    >
    > __forceinline myStr operator+=(const char * source)
    > {
    > printf("Add Static Length\n");
    > // HELP !!!! --> why does he not inline the function and precalculate
    > strlen() at compiletime ? is there a method ?
    > like: templates or so ?
    >
    > AppendString(source,strlen(source));
    > return *this;
    > }
    >
    > };
    >
    > int _tmain(int argc, _TCHAR* argv[])
    > {
    > myStr test;
    > test += "HHHHHHHHHHHHH"; //= 13 bytes = 0xd
    > test.AppendString("HHHHHHHHHHHHH",strlen("HHHHHHHHHHHHH"));
    > return 0;
    > }
    >
    >
    >
    > thx
    >
    > franz
    >
    >


    Yeah, the preprocessor should implement a strlen function for
    compile-time. As long as the convention for character string literals
    is the null-terminated C string, it should be easy to implement a strlen
    function for literals at compile time, c_str_sizeof or whatnot.

    I wonder why there hasn't been a standard preprocessor strlen macro for
    twenty years (for C/C++, for m4 the preprocessor or so). Surely it's
    been discussed widely before, can someone point to discussions as to why
    there is not that feature?

    The stringify and identifier concatenations in the preprocessor (# and
    ##) can be useful, in for example faking templates. (Not exactly faking
    them, but implementing templates using the preprocessor and nested macro
    definitions with funny header includes and template type redefinitions,
    in C. ) The upcoming variadic macros in C++ are going to be highly
    abused, they would be useful for a lot of repetitive list generation in
    simple list to structure translation, for example defining enums and as
    well functions to return strings with the names and so on, except there
    will probably be problems with getting the commas only among the
    identifiers, in fragile/brittle preprocessor enumeration.

    Anyways, while that may be so, it would also be useful to have a strlen
    macro. The compiler already knows the layout of the data, it's a
    compile time invariant, and would allow things like conventions about
    storing word dictionaries as offset/length pairs in large strings, with
    no null-terminated storage, besides just enabling simple writes of those
    things.

    Where are the interminable discussions about strlen macro and why/why
    not it is already standard?

    Ross F.
     
    Ross A. Finlayson, Apr 11, 2008
    #2
    1. Advertising


  3. > Anyways, while that may be so, it would also be useful to have a strlen
    > macro. The compiler already knows the layout of the data, it's a
    > compile time invariant, and would allow things like conventions about
    > storing word dictionaries as offset/length pairs in large strings, with
    > no null-terminated storage, besides just enabling simple writes of those
    > things.
    >
    > Where are the interminable discussions about strlen macro and why/why
    > not it is already standard?
    >


    I guess there is sizeof for array types that returns the size of the
    array, but literals are generally const char* types.

    sizeof("xyz") == sizeof(char*); // <- not strlen

    char xyz[] = "xyz"

    sizeof(xyz) == 4 ; // <- not strlen

    So, maybe it is as simple as to declare the C strings as character
    arrays, and subtract 1, where sizeof(char)==1.

    #define strlen_macro(char_arr) (sizeof(char_arr)/sizeof(char)-1)

    Yet, still I wonder about the correct const char* <-> char[]
    declarations, in terms of whether when the compiler sees a character
    string literal, whether it is treated as a char* or char[] in terms of
    sizeof (the operator/compiler facility). Does sizeof("xyz") always
    return sizeof(char*), or sizeof(char)*4, as defined behavior?

    Ross F.
     
    Ross A. Finlayson, Apr 11, 2008
    #3

  4. > Yet, still I wonder about the correct const char* <-> char[]
    > declarations, in terms of whether when the compiler sees a character
    > string literal, whether it is treated as a char* or char[] in terms of
    > sizeof (the operator/compiler facility). Does sizeof("xyz") always
    > return sizeof(char*), or sizeof(char)*4, as defined behavior?
    >


    OK, modern C++ string literals are const char[], before they were
    char[], so a strlen_macro is easy to implement.

    Ross F.
     
    Ross A. Finlayson, Apr 11, 2008
    #4
  5. news.inode.at

    Lehner Franz Guest

    i fully agree with your position of "why is there no macro for strlen() like
    it is for sizeof() ...)

    even if not, the 2'nd chance would be an abstraction to the operator+= like

    myStr operator+=(const char * source)
    myStr operator+=(char * source)
    as compiler already sees operation like Str test += "hello"; as const char
    operation (ok, this is cool)
    but how to use this information then ?
    why is there no thing like
    myStr operator+=(const char * source,strlen(source)) <- where preprocessor
    automatically does an inline expand ??

    and why
    3'rd chanche
    as:

    test.AppendString("HHHHHHHHHHHHH",strlen("HHHHHHHHHHHHH"));

    really does a inline "pre-length" calculation (look to /o2)
    and it is in ASM
    test.AppendString("HHHHHHHHHHHHH",13)); <- cool

    but why the hell can i not inline the += operator into it ????


    and yes, you are right, doing this

    myStr operator+=(const char * source)
    {
    printf("Add Static Length\n");
    AppendString(source,sizeof(source)); <- sizeof == 4 now , because function
    gets not inlined !!!
    return *this;
    }

    this is all "sh.t"

    you think there is no chance with a function template ? (i am not very good
    in them ..) ?

    franz


    "Ross A. Finlayson" <> schrieb im Newsbeitrag
    news:ftolj0$u5c$...
    >
    >> Anyways, while that may be so, it would also be useful to have a strlen
    >> macro. The compiler already knows the layout of the data, it's a compile
    >> time invariant, and would allow things like conventions about storing
    >> word dictionaries as offset/length pairs in large strings, with no
    >> null-terminated storage, besides just enabling simple writes of those
    >> things.
    >>
    >> Where are the interminable discussions about strlen macro and why/why not
    >> it is already standard?
    >>

    >
    > I guess there is sizeof for array types that returns the size of the
    > array, but literals are generally const char* types.
    >
    > sizeof("xyz") == sizeof(char*); // <- not strlen
    >
    > char xyz[] = "xyz"
    >
    > sizeof(xyz) == 4 ; // <- not strlen
    >
    > So, maybe it is as simple as to declare the C strings as character arrays,
    > and subtract 1, where sizeof(char)==1.
    >
    > #define strlen_macro(char_arr) (sizeof(char_arr)/sizeof(char)-1)
    >
    > Yet, still I wonder about the correct const char* <-> char[] declarations,
    > in terms of whether when the compiler sees a character string literal,
    > whether it is treated as a char* or char[] in terms of sizeof (the
    > operator/compiler facility). Does sizeof("xyz") always return
    > sizeof(char*), or sizeof(char)*4, as defined behavior?
    >
    > Ross F.
     
    Lehner Franz, Apr 11, 2008
    #5
  6. Lehner Franz wrote:
    > ...
    > but why the hell can i not inline the += operator into it ????
    >
    >


    I think maybe if you put the definition in the class declaration, also
    with the inline keyword, maybe it will inline the implementation.

    class Str{

    inline operator +=(Str& other){
    // ...
    return *this;
    }

    };

    I think if you put the inline definition in the class declaration then
    it will inline the implementation, otherwise the object won't link with
    the multiple copies of the definition.

    Ross F.
     
    Ross A. Finlayson, Apr 11, 2008
    #6
  7. Lehner Franz wrote:
    > even if not, the 2'nd chance would be an abstraction to the operator+= like
    >
    > myStr operator+=(const char * source)
    > myStr operator+=(char * source)
    > as compiler already sees operation like Str test += "hello"; as const char
    > operation (ok, this is cool)
    > but how to use this information then ?
    > why is there no thing like
    > myStr operator+=(const char * source,strlen(source)) <- where preprocessor
    > automatically does an inline expand ?


    The fact that the characters where source point to are constant does in
    no way imply that source is constant. Think about:

    const char* str = some_flag ? "abc" : "defghi";

    You still can call myStr::eek:perator+=(const char * source) with str. In
    fact you should not define myStr::eek:perator+=(char * source) because the
    += operator should not modify it's right operand anyway.

    > and why
    > 3'rd chanche
    > as:
    >
    > test.AppendString("HHHHHHHHHHHHH",strlen("HHHHHHHHHHHHH"));
    >
    > really does a inline "pre-length" calculation (look to /o2)
    > and it is in ASM
    > test.AppendString("HHHHHHHHHHHHH",13)); <- cool
    >
    > but why the hell can i not inline the += operator into it ????


    because the information about the length is lost at the moment that
    'const char (&)[14]' is converted to 'const char*'.

    But you can do that:

    template <size_t L>
    myStr operator+=(const char (&source)[L])
    {
    // use L-1 assuming source is zero terminated ???
    }

    But as you see L will be 14, because it is the physical size of the
    array. The logical size is usually one less. But this is not required at
    all. Think about:
    const char str[20] = "abc";


    > and yes, you are right, doing this
    >
    > myStr operator+=(const char * source)
    > {
    > printf("Add Static Length\n");
    > AppendString(source,sizeof(source)); <- sizeof == 4 now , because function
    > gets not inlined !!!


    That's not the reason. source is simply another type. Your string is
    implicitly converted to this type.


    > return *this;
    > }
    >
    > this is all "sh.t"
    >
    > you think there is no chance with a function template ? (i am not very good
    > in them ..) ?


    See above, but it won't help you too much.


    The origin of the whole problem is different. The C++ language does not
    provide a compile time constant attribute of expressions (at least not
    to the user) and it does not provide a functional method attribute.
    In fact the result of a functional method whose arguments are all
    compile time constants will be a compile time constant too. And so the
    function may be evaluated at compile time. The compilers internally use
    this paradigm for built-in functions (as your compiler obviously did
    with strlen), but this is always an internal optimization. It is not
    part of the language. A user cannot write a function with the same
    properties.

    I ran into this problem significantly more than once. Of course, it is
    not that easy to implement. At least if you are cross compiling you will
    always need a emulation of the target platform. Or you need to compile
    in two steps. Firstly to an internal intermediate representation,
    secondly to the targets machine code. As far as I know gcc operates this
    way.


    Marcel
     
    Marcel Müller, Apr 12, 2008
    #7
    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. Piotre Ugrumov
    Replies:
    3
    Views:
    375
    Nick Hounsome
    Jan 25, 2004
  2. david ullua
    Replies:
    13
    Views:
    669
  3. raan
    Replies:
    2
    Views:
    452
  4. Buzz Lightyear
    Replies:
    10
    Views:
    1,124
    Alexander Bartolich
    Aug 12, 2009
  5. Ying-Chieh Liao

    function overload (not operator overload)

    Ying-Chieh Liao, Oct 11, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    255
    Sherm Pendley
    Oct 11, 2004
Loading...

Share This Page