Decyphering an assertion

A few weeks ago, I posted a humdinger of an assertion.

A little investigation shows that this is actually the very legible

assert (strncmp (repository, current_parsed_root->directory,
                 strlen (current_parsed_root->directory)) == 0);
but the glibc headers have code which turns strncmp(c1, c2, n) into strcmp(c1, c2) when one of the strings is constant and shorter than n (this probably happens a lot in defensive code):
#ifndef _HAVE_STRING_ARCH_strncmp
# define strncmp(s1, s2, n)                                                   \
  (__extension__ (__builtin_constant_p (n)                                    \
                  && ((__builtin_constant_p (s1)                              \
                       && strlen (s1) < ((size_t) (n)))                       \
                      || (__builtin_constant_p (s2)                           \
                          && strlen (s2) < ((size_t) (n))))                   \
                  ? strcmp (s1, s2) : strncmp (s1, s2, n)))
#endif
while strcmp is in turn defined to a completely nutty bit of code which seems to have something to do with inlining comparisons where at least one string is a short constant string (again, something that may happen quite a bit in practice).

I am a lover of macros, having written a few humdingers of my own, but nothing to rival the sheer majesty of the ones found in glibc's internal headers. If you value your sanity, you'll steer clear of <bits/string2.h>.

As a parting gift, here's one of the "humdingers" I recently wrote, part of a Python wrapper for part of the OpenGL API:

#define GLCALL4V(name, fmt, t1, t2, t3, t4) \
static PyObject *py##name(PyObject *s, PyObject *o) { \
    t1 p1; t2 p2; t3 p3; t4 p4; \
    if(!PyArg_ParseTuple(o, fmt, &p1, &p2, &p3, &p4)) return NULL; \
    name(p1, p2, p3, p4); \
    CHECK_ERROR; \
    Py_INCREF(Py_None); return Py_None; \
}
(tsk tsk, I didn't carefully align the backslashes like the glibc author)

It's used like this:

GLCALL4V(gluPerspective, "dddd", double, double, double, double);
which I defend as a really convenient way to write the wrapper for the gluPerspective call. But at the same time, I can imagine the horror of some future maintainer of my software, the first time he sees my macro. Don't worry. This burst of empathy won't actually change the way I write software...

Entry first conceived on 1 December 2005, 2:10 UTC, last modified on 15 January 2012, 3:46 UTC
Website Copyright © 2004-2024 Jeff Epler