Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > inline overload operation question

Reply
Thread Tools

inline overload operation question

 
 
news.inode.at
Guest
Posts: n/a
 
      04-11-2008
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("HHHHHHHH HHHHH"));
return 0;
}



thx

franz


 
Reply With Quote
 
 
 
 
Ross A. Finlayson
Guest
Posts: n/a
 
      04-11-2008
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("HHHHHHHH HHHHH"));
> 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.


 
Reply With Quote
 
 
 
 
Ross A. Finlayson
Guest
Posts: n/a
 
      04-11-2008

> 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.
 
Reply With Quote
 
Ross A. Finlayson
Guest
Posts: n/a
 
      04-11-2008

> 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.


 
Reply With Quote
 
Lehner Franz
Guest
Posts: n/a
 
      04-11-2008
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("HHHHHHHH HHHHH"));

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" <(E-Mail Removed)> schrieb im Newsbeitrag
news:ftolj0$u5c$(E-Mail Removed)...
>
>> 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.



 
Reply With Quote
 
Ross A. Finlayson
Guest
Posts: n/a
 
      04-11-2008
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.
 
Reply With Quote
 
Marcel Müller
Guest
Posts: n/a
 
      04-12-2008
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:perator+=(const char * source) with str. In
fact you should not define myStr:perator+=(char * source) because the
+= operator should not modify it's right operand anyway.

> and why
> 3'rd chanche
> as:
>
> test.AppendString("HHHHHHHHHHHHH",strlen("HHHHHHHH HHHHH"));
>
> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Boolean operation and arithmetic operation Buzz Lightyear C++ 10 08-12-2009 01:27 PM
I/O operation, file operation behaviou raan C++ 2 08-16-2007 07:13 PM
Does bit operation always work more efficiently than math operation? david ullua C Programming 13 03-01-2006 11:02 PM
function overload (not operator overload) Ying-Chieh Liao Perl Misc 3 10-11-2004 11:24 AM
How use the overload of>> (or<<) of a class in the overload of << and >> of another class? Piotre Ugrumov C++ 3 01-25-2004 08:08 PM



Advertisments