patterncMajor
Length of a C string, capped to some maximum
Viewed 0 times
maximumlengthsomecappedstring
Problem
If I have a oneliner in C such as
would it be better to have a macro defined such that
or would it be better to have
Also, is there a way to turn the second function into a macro for maximum efficiency?
size_t maxSizeOf(const char *s)
{
return strlen(s) > M_MAX_SIZE ? M_MAX_SIZE : strlen(s);
}would it be better to have a macro defined such that
#define MAX_SIZE_OF(s) (strlen(s) > M_MAX_SIZE ? M_MAX_SIZE : strlen(s))or would it be better to have
size_t maxSizeOf(const char *s)
{
size_t len = strlen(s);
return len > M_MAX_SIZE ? M_MAX_SIZE : len;
}Also, is there a way to turn the second function into a macro for maximum efficiency?
Solution
All three versions can be improved.
The first function has the problem that
The second version (the macro) has the same issue, with the additional caveat that it breaks if
and possibly lead to
The last version is better, in that it avoids both the second call to
First, I think that you would be better off decomposing the problem into two parts, like
Second, if the string that is passed to the function is much longer than
More importantly, worrying about the efficiency of the function compared to the macro is a false optimization. The operation that could potentially take a long time and scale poorly is
The first function has the problem that
strlen(s) is likely to be called twice. strlen() is an expensive operation, as it walks along the entire string until it finds the NUL terminator.The second version (the macro) has the same issue, with the additional caveat that it breaks if
s is an expression with a side-effect, such as an assignment. For example, MAX_SIZE_OF(str++) would expand to(strlen(str++) > M_MAX_SIZE ? M_MAX_SIZE : strlen(str++))and possibly lead to
str being incremented twice. (Even if you decide that the ALL_CAPS_NAME alerts programmers to the fact it is a macro and thus susceptible to this kind of thing, it's still a trap that is better avoided altogether.)The last version is better, in that it avoids both the second call to
strlen() and the double-argument-expansion problem. However, I still have two objections.First, I think that you would be better off decomposing the problem into two parts, like
MIN(M_MAX_SIZE, strlen(s)). The MIN() macro, although not in the C standard, is frequently reimplemented, and widely understood. On the other hand, it is less obvious what your maxSizeOf() is supposed to do. I'm not sure that it's even worth the brain power to keep track of the existence of this function.Second, if the string that is passed to the function is much longer than
M_MAX_SIZE, it still needs to walk all the way to the end of the string — even if M_MAX_SIZE is 5 and the string is a gigabyte long. To avoid that problem, I think that you may be better off walking down s yourself. And if you do hunt for the NUL terminator yourself, then it is suddenly worthwhile to have this function again.More importantly, worrying about the efficiency of the function compared to the macro is a false optimization. The operation that could potentially take a long time and scale poorly is
strlen(). That's the performance problem that would bite you — not the function-vs.-macro stuff that you are worrying about.Code Snippets
(strlen(str++) > M_MAX_SIZE ? M_MAX_SIZE : strlen(str++))Context
StackExchange Code Review Q#115553, answer score: 20
Revisions (0)
No revisions yet.