Howard Chu writes:
Hallvard B Furuseth wrote:
[Rearranging a little]
Since this is all ber/LBER, it should go in an lber_* header file, not ac/assert.h.
OK. I guess that means lber_pvt.h: ber_pvt_assertz(), ber_pvt_static_assert() since on second thought I don't see much need to export it in installed headers. After all there's nothing BER/LDAP-specific about asserts. Opinions?
liblber will need a dummy variable 'const char ber_assertion[1];'. We can drop that if anyone dislikes it: ber_static_assert() can take an assertion_name parameter and declare a typedef based on that name. Or it can generate a name from __LINE__. Then we can have only one static assert per line, which matters for macros but little else.
Also the __LINE__ variant must not be used in headers, since then we can have name clashes between assertions in different .h/.c files:-(
You could avoid the naming issue by just enclosing the body in a block {}. I'm assuming we only need this inside functions, and not at file scope.
We don't need it, but it's cleaner with the assertion near the code it asserts about - and we do have file-scope assumptions like "<file-scope array X> has length Y", e.g. relay_fail_modes[] in back-relay/op.c.
However ber_pvt_static_assert() is just a convenience wrapper around ber_pvt_assertz(): ber_pvt_static_assert(cond); can be replaced with (void) ber_pvt_assertz(cond); for an {} assert, and enum { some_name = ber_pvt_assertz(cond) }; for a declaration assert.
So whatever we do for ber_pvt_static_assert(), if it doesn't fit the needs of some piece of code it can use one of the latter forms. I prefer it as a declaration since that helps with the ugliest (and longest) syntax.
I too prefer to avoid a name parameter, so if a linker symbol is a problem I suggest the __LINE__ variant for now. We can also add a symbol the macro can use in the future, but not use it yet to keep compatibility with existing binaries.
BTW, yet another trick is to stuff the assertion into the prototype of an existing function: LBER_F(void) ber_pvt_sb_buf_init LDAP_P((Sockbuf_Buf *buf)); becomes LBER_F(void) ber_pvt_sb_buf_init(Sockbuf_Buf buf[assertz expression]); which is supposed to be equivalent - and we already require ISO C for internal files.