inline overload operation question

N

news.inode.at

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
 
R

Ross A. Finlayson

news.inode.at said:
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.
 
R

Ross A. Finlayson

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

Ross A. Finlayson

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

Lehner Franz

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 said:
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.
 
R

Ross A. Finlayson

Lehner said:
> ...
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.
 
M

Marcel Müller

Lehner said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top