On 10/31/2012 06:06 AM, Borislav Petkov wrote: >> Realistically, a single macro could be defined in compiler*.h that >> encapsulates the entirety of this mechanism and only exposes a "black >> box" macro, that will simply expand to something that breaks the build >> in the most appropriate fashion based upon the version of gcc. In >> essence, the new BUILD_BUG_ON_MSG macro attempts to fill that roll. > > Yes. OK, so I have two solutions, one I like and one that I don't. Both of these solutions will use the __compiletime_error_fallback macro, but cleaned up slightly and it will only be used from within compiler.h (so it becomes a private macro). #ifndef __compiletime_error # define __compiletime_error(message) # define __compiletime_error_fallback(condition) \ do { ((void)sizeof(char[1 - 2*!!(condition)])); } while (0) #else # define __compiletime_error_fallback(condition) do { } while (0) #endif And now let me present the solution that I do not like. // compiler.h (after the above snippet) #define __compiletime_error_invoke(condition, func) \ do { \ bool __cond = !!(condition); \ if (__cond) \ func(); \ __compiletime_error_fallback(__cond); \ } while (0) #endif // bug.h ... #define __BUILD_BUG_INTERNAL(condition, msg, line) \ do { \ extern void __build_bug_on_failed_ ## line(void)\ __compiletime_error(msg); \ __compiletime_error_invoke(condition, \ __build_bug_on_failed_ ## line) \ } while (0) #define _BUILD_BUG_INTERNAL(condition, msg, line) \ __BUILD_BUG_INTERNAL(condition, msg, line) Rather than using __compiletime_error_fallback externally anywhere, we just use it in another macro in compiler.h. Then, this __compiletime_error_invoke macro is actually called to invoke the error. This problem is that this is highly disjointed; we end up with large parts of the implementation in both compiler.h and in bug.h. (also, I think we would need another macro to expand the concatenation of __build_bug_on_failed_ ## line, I didn't test the above). If we are going to move this level of detail out of bug.h, I think we should move *all* of it. // compiler.h ... #define __compiletime_assert(condition, msg, __func) \ do { \ bool __cond = !!(condition); \ extern void __func(void) __compiletime_error(msg); \ if (__cond) \ __func(); \ __compiletime_error_fallback(__cond); \ } while (0) #define _compiletime_assert(condition, msg, __func) \ __compiletime_assert(condition, msg, __func) /** * compiletime_assert - some documentation... */ #define compiletime_assert(condition, msg) \ __compiletime_assert(condition, msg, __compiletime_assert_ ## __LINE__) // bug.h -- remove *BUILD_BUG_INTERNAL macros entirely and just chance this: #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(cond, msg) To me, this is much cleaner. It will give all compile-time assertions the same base function name, but this shouldn't be much of a problem since the new error attribute will spit out a nice detailed error message at the point the error occurs and few people (if any?) should be having to track this down from the link-time error. Even if you are having to track it down just from a link-time error, it will tell you the object file that the function was called from and the line number is embedded in the function name, so it wouldn't be too hard. For example, it's possible that the link-time error may be the only thing that breaks on Intel or some other compilers (clang?). Having the full implementation in compiler*.h allows for easier tweaking to suit various compilers as well. (I may need to load up intel's latest compiler and see how it is there). Anyway, please let me know if you like it. Daniel -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html