Reputation: 3435
Sometimes it is necessary to compare a string's length with a constant.
For example:
if ( line.length() > 2 )
{
// Do something...
}
But I am trying to avoid using "magic" constants in code.
Usually I use such code:
if ( line.length() > strlen("[]") )
{
// Do something...
}
It is more readable, but not efficient because of the function call.
I wrote template functions as follow:
template<size_t N>
size_t _lenof(const char (&)[N])
{
return N - 1;
}
template<size_t N>
size_t _lenof(const wchar_t (&)[N])
{
return N - 1;
}
// Using:
if ( line.length() > _lenof("[]") )
{
// Do something...
}
In a release build (VisualStudio 2008) it produces pretty good code:
cmp dword ptr [esp+27Ch],2
jbe 011D7FA5
And the good thing is that the compiler doesn't include the "[]" string in the binary output.
Is it a compiler specific optimisation or is it a common behavior?
Upvotes: 12
Views: 10948
Reputation: 248289
I think most compilers will optimize it away when optimizations are enabled. If they're disabled, it might slow your program down much more than necessary.
I would prefer your template functions, as they're guaranteed to not call strlen
at runtime.
Of course, rather than writing separate functions for char
and wchar_t
, you could add another template argument, and get a function which works for any type:
template <typename Char_t, int len>
int static_strlen(const Char_t (&)[N] array){
return len / sizeof(Char_t) - 1;
}
(As already mentioned in comments, this will give funny results if passed an array of ints, but are you likely to do that? It's meant for strings, after all)
A final note, the name _strlen
is bad. All name at namespace scope beginning with an underscore are reserved to the implementation. You risk some nasty naming conflicts.
By the way, why is "[]" less of a magic constant than 2 is?
In both cases, it is a literal that has to be changed if the format of the string it is compared to changes.
Upvotes: 3
Reputation: 15974
#define TWO 2
#define STRING_LENGTH 2
/* ... etc ... */
Seriously, why go through all this hassle just to avoid typing a 2? I honestly think you're making your code less readable, and other programmers are going to stare at you like you're snorting the used coffee from the filter.
Upvotes: -12
Reputation: 212674
Why not
sizeof "[]" - 1;
(minus one for the trailing null. You could do sizeof "[]" - sizeof '\0', but sizeof '\0' is often sizeof( int ) in C, and "- 1 " is perfectly readable.)
Upvotes: 15
Reputation: 163357
The capability to inline a function call is both a compiler-specific optimization and a common behavior. That is, many compilers can do it, but they aren't required to.
Upvotes: 6