HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMajor

Length of a C string, capped to some maximum

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
maximumlengthsomecappedstring

Problem

If I have a oneliner in C such as

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