<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">And I do agree that it can be inconvenient to deal with these warnings in heavily #ifdef’d code. I think there are some good strategies for avoiding that, and I’d like to talk about specific irritating cases so I can propose the strategy I’d push for. Generally the strategy is to push more configuration specifics to the edges rather than spreading them through multiple functions.<br class=""></div></blockquote><div><br class=""></div></div>A few irritating cases for me:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">(1)</div><div class=""><br class=""></div><div class=""><div class="">static inline void validate(const Range&amp; range)</div></div><div class=""><div class="">{</div></div><div class=""><div class="">&nbsp; &nbsp; UNUSED(range);</div></div><div class=""><div class="">IF_DEBUG(</div></div><div class=""><div class="">&nbsp; &nbsp; BeginTag* beginTag = LargeChunk::beginTag(range.begin());</div></div><div class=""><div class="">&nbsp; &nbsp; EndTag* endTag = LargeChunk::endTag(range.begin(), range.size());</div></div><div class=""><div class=""><br class=""></div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(!beginTag-&gt;isEnd());</div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(range.size() &gt;= largeMin);</div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(beginTag-&gt;size() == range.size());</div></div><div class=""><div class=""><br class=""></div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(beginTag-&gt;size() == endTag-&gt;size());</div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(beginTag-&gt;isFree() == endTag-&gt;isFree());</div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(beginTag-&gt;hasPhysicalPages() == endTag-&gt;hasPhysicalPages());</div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(static_cast&lt;BoundaryTag*&gt;(endTag) == static_cast&lt;BoundaryTag*&gt;(beginTag) || endTag-&gt;isEnd());</div></div><div class=""><div class="">);</div></div><div class=""><div class="">}</div></div><div class=""><br class=""></div><div class="">(2)</div><div class=""><br class=""></div><div class=""><div class="">inline void vmValidate(size_t vmSize)</div></div><div class=""><div class="">{</div></div><div class=""><div class="">&nbsp; &nbsp; // We use getpagesize() here instead of vmPageSize because vmPageSize is</div></div><div class=""><div class="">&nbsp; &nbsp; // allowed to be larger than the OS's true page size.</div></div><div class=""><div class=""><br class=""></div></div><div class=""><div class="">&nbsp; &nbsp; UNUSED(vmSize);</div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(vmSize);</div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(vmSize == roundUpToMultipleOf(static_cast&lt;size_t&gt;(getpagesize()), vmSize));</div></div><div class=""><div class="">}</div></div><div class=""><div class=""><br class=""></div></div><div class="">(3)</div><div class=""><br class=""></div><div class=""><div class="">inline void vmValidate(void* p, size_t vmSize)</div></div><div class=""><div class="">{</div></div><div class=""><div class="">&nbsp; &nbsp; // We use getpagesize() here instead of vmPageSize because vmPageSize is</div></div><div class=""><div class="">&nbsp; &nbsp; // allowed to be larger than the OS's true page size.</div></div><div class=""><div class=""><br class=""></div></div><div class=""><div class="">&nbsp; &nbsp; vmValidate(vmSize);</div></div><div class=""><div class="">&nbsp; &nbsp;&nbsp;</div></div><div class=""><div class="">&nbsp; &nbsp; UNUSED(p);</div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(p);</div></div><div class=""><div class="">&nbsp; &nbsp; BASSERT(p == mask(p, ~(getpagesize() - 1)));</div></div><div class=""><div class="">}</div></div></blockquote><div class=""><div class=""><br class=""></div></div><div class="">The common theme in these cases is that I wanted to write a helper function to do some ASSERTs which compiled to nothing in a release build. Compiling the function to nothing made its parameters look like errors.</div><div class=""><br class=""></div><div class="">I considered having the validate function return a value, and having the caller ASSERT(validate(x)) — that way, the call would compile to nothing, and the callee would always appear to do something with its parameters. I didn’t like that solution for two reasons:</div><div class=""><br class=""></div><div class="">(1) When debugging or reading a crash report, I wanted the indicated line of code to be the specific condition that failed. If the caller ASSERTs after a long line of reasoning, the indicated line of code is the non-specific ASSERT in the caller. This was a big deal to me.</div><div class=""><br class=""></div><div class="">(2) In cases where one validate needed to call another, I sometimes still had an unused parameter in the caller.</div><div class=""><br class=""></div><div class="">Geoff</div></body></html>