Re: [PATCH] utilize _Static_assert() for BUILD_BUG_ON() when thecompiler supports it

From: Daniel Santos
Date: Wed Dec 12 2012 - 19:47:58 EST


On 11/06/2012 03:23 AM, Jan Beulich wrote:
This sort of logic is normally performed via the
include/linux/compiler*.h system. And

grep __GNUC include/linux/*.h

indicates that we've been pretty successful. Can we do that here too?

(eg: suppose the Intel compiler supports _Static_assert?)
Yeah, there are a lot of goodies here:

_Static_assert:
We could define __ASSERT_STRUCT_FIELD(e) for this:
#define BUILD_BUG_ON_ZERO(e) \
sizeof(struct { __ASSERT_STRUCT_FIELD(e); })
I considered something like this too, but it wouldn't work well: The
diagnostic issued from a failed _Static_assert() would preferably
refer to the original source expression, not an already macro
expanded variant of it. That, however, precludes passing it
through multiple levels of macro expansion. Which would leave
passing e and #e to __ASSERT_STRUCT_FIELD(), but that's again
ugly as it opens the door for someone adding a use where the two
arguments don't match up.
I was under the assumption that _Static_assert doesn't exist unless you are using -std=c11 or -std=gnu11, but I admit I didn't look into it much. I'm very glad it was added to the standard. IMO, it would be better to use such a feature (presuming it behaves well) when it is available but, of course, we still need the best possible functionality when it isn't.

In either case, the new BUILD_BUG_ON macro simply stringifies the condition, so it will emit an error indicating the exact expression that failed. If you pass it a macro, macro expansion will not be performed prior to stringification.

__compiletime_error():
I blame Arjan for this. It disappears if not implemented, which
is just lazy. BUILD_BUG_ON() does this right, and he didn't fix
that at the time :(
Again, the name of the macro made me not use it, as the obvious
fallback is a link time error. The only thing I would be agreeable to
is something like __buildtime_error().

Yeah, I agree, since we speak more in terms of a "build" rather than compiling. But I didn't mess with it in my patches.


I'd say we have three patches here, really:

1) Add __ASSERT_STRUCT_FIELD(e) to compiler.h
There are actually a number of reasons for having multiple mechanisms to break the build. For instance, BUILD_BUG_ON_ZERO is used outside of function bodies, where a compound gcc expression ({expr; expr;}) isn't permitted.
2) Add __UNIQUE_ID().
3) Use them (I can think of at least one other place for __UNIQUE_ID()).

Jan, do you want the glory? :) If not, I'll respin.
Depending on the answers to the above (i.e. how much of it
actually would need re-doing and re-testing), it may take me
some time to get to this, but beyond that I'm fine with trying
to improve this to everyone's satisfaction.
Personally, I would rather we start a cpputil.h (or some such) to encapsulate all of our preprocessor kludgery, err, I mean wizardry. There must be 14 thousand paste macros in the kernel. We could move stringify into it as well, but I suppose that's another issue.

Daniel
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/