Boost logo

Boost :

Subject: Re: [boost] Compiler Warnings Tests
From: Vicente Botet Escriba (vicente.botet_at_[hidden])
Date: 2009-11-28 16:42:30


Stewart, Robert wrote:
>
> Vicente Botet Escriba wrote:
>
> [Vicente, please don't overquote]
>
>

Hi,

Apologize for the over quoting, I'm not working from my usual environment.

>
>> Robert Ramey wrote:
>> > Paul A. Bristow wrote:
>> >>
>> >> The Microsoft docs examples might be a good start?
> [snip]
>> >> So are you proposing a collection of these, with versions
>> >> that should compile and others that should not,...
>> >>
>> >> Or am I still misunderstanding you?
>> >
>> > You've got it.
>> >
>> > The only difference would be that the warning shouldn't be
>> > associated with a particular compiler.
>>
>> We need to have a test that probes the warning is present for
>> some compilers. The simple way is to build with
>> warnigs_as_errors=on and check that the compilation fails.
>>
>> We need of course check that the workaround or a better
>> coding style solves the issue. This needs to be done also
>> with warnigs_as_errors=on and check that the compilation
>> succeeds.
>>
>> And last, in some cases, we need to check that with
>> warnigs_as_errors=off both are equivalent. This needs to be
>> done with warnigs_as_errors=off and check the test run
>> succeed.
>
> That seems quite reasonable.
>
>> int main() {
>> int b = 30000, c = 30000;
>> #if defined(BOOST_WARNING_AS_ERROR_MUST_FAIL)
>> short a = b + c; // C4244
>> #elif undefined(BOOST_WARNING_AS_ERROR_MUST_SUCCEED)
>> short a = static_cast<unsigned short>(b + c);
>> #else
>> short a1 = b + c; // C4244
>> short a2 = static_cast<unsigned short>(b + c);
>> assert(a1==a2)
>> #endif
>> }
>
> I see what you're trying to do, but I dislike the duplication,
> particularly as some tests may require a good deal of setup. That example
> could be recast as:
>
> int
> main()
> {
> int b(30000);
> int c(30000);
> #if defined (BOOST_WARNING_AS_ERROR_MUST_FAIL) \
> || !defined (BOOST_WARNING_AS_ERROR_MUST_PASS)
>
> short a1(b + c); // MSVC: C4244
>
> #endif
> #if defined (BOOST_WARNING_AS_ERROR_MUST_PASS) \
> || !defined (BOOST_WARNING_AS_ERROR_MUST_FAIL)
>
> short a2(static_cast<unsigned short>(b + c));
>
> #endif
> #if !defined (BOOST_WARNING_AS_ERROR_MUST_PASS) \
> && !defined (BOOST_WARNING_AS_ERROR_MUST_FAIL)
>
> assert(a1 == a2);
>
> #endif
> }
>
> Obviously, the macros add a lot of line noise, so we could construct
> simpler manifest constants that represent the three conditions:
> BOOST_WARNING_TEST_FAIL_OR_IGNORE, BOOST_WARNING_TEST_PASS_OR_IGNORE, and
> BOOST_WARNING_TEST_IGNORE might do.
>
>
>

Thanks for all the suggested improvements. You're right duplication is not
good. Your approach seems to solve this issue.

>
>> The question no is how to use this test on compiler that
>> don't warm in this case.
>>
>> An here is where we can not be independent of the compiler. We need to
>> determine on the code if the compiler must warms or not:
>
> [snip code trying to trigger a warning when the compiler doesn't]
>
> It might be possible to wrap the code that is supposed to warn with a
> macro that dictates the expected behavior:
>
> BOOST_MUST_WARN(short a1(b + c));
>
> Assuming that is possible, then BOOST_MUST_WARN will rely on the supplied
> statement to warn when a compiler is expected to warn in that situation,
> and will force a warning or some other failure, when it isn't. There
> would then be preprocessor conditional logic to determine whether
> BOOST_MUST_WARN needs to force a warning/compilation error or not, based
> upon the compiler being used, as well as to pass through the code for the
> equivalence test. That logic will be largely boilerplate and will appear
> outside the test code, making the test code more readable.
>
> Given that mechanism, the example becomes the following:
>
> int
> main()
> {
> int b(30000);
> int c(30000);
> BOOST_MUST_WARN(short a1(b + c)); // MSVC: C4244
> short a2(static_cast<unsigned short>(b + c));
> #ifdef BOOST_WARNING_TEST_IGNORE
> assert(a1 == a2);
> #endif
> }
>
> Since initializing a1 is expected to warn on MSVC, the macro will just
> emit the supplied code when testing for failure with warnings-as-errors.
> The macro must also emit the code for the warnings-as-warnings equivalence
> test. For a no-warnings test, the macro must emit nothing.
>
> For a compiler that doesn't emit a warning for that statement,
> BOOST_MUST_WARN must be defined to produce a warning (or to otherwise fail
> the compilation) in a warnings-as-errors test. Otherwise, it must simply
> emit the code unchanged.
>
>

I think that BOOST_MUST_WARN don't works as it must add a #warning depending
on the statement and the compiler.

>
> The initialization of a2 is expected to produce no warnings in any case,
> so it needn't be special cased.
>
>

Right

> The assertion -- or other equivalence test code in other cases -- might
> only be desirable in the equivalence test, hence the conditional
> compilation.
>
> The foregoing assumes, of course, that the warning-generating code can be
> reduced to a statement and that all desired statements can be captured as
> shown.
>
>

Yes, when the assumption is false a ifdef could be preferable.

Best,
Vicente

-- 
View this message in context: http://old.nabble.com/Compiler-Warnings-Tests-tp26545937p26557179.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk