
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Robert Ramey Sent: Friday, November 27, 2009 5:07 PM To: boost-users@lists.boost.org Cc: boost@lists.boost.org Subject: Re: [Boost-users] Compiler warnings from Macs, IBM acc, Borland, Comeau, Metroworks, et al - are they a Problem?
I know this suggestion has been made but I want to expand a little on it.
a "library" - warning policy test. This would be just like any other library as far as the testing system goes. It would have maybe 10? small compile only tests which would emit warnings or not. The source would describe which warning is in fact being tested.
Presumably, the test matrix would permit one to look at the warning messages. (I'm not sure that the current one does this).
In anycase, it would permit the test matrix be used to check the warning status for each warning on each compiler at a specified warning level.
I see this as the only way to get a real grip on how these things vary among the array of compiler's we might use.
I realize that it would be some work, but I would think it wouldn't be all that much more - if any - than that which has already been expended on the wiki. It would have the great advantage of being relatively free of "maintainence by hand". It would automate the whole process of determining the status of different compilers in this area.
OK I can see some merit in this (now I understand your proposal a bit more). And I'm starting a new thread for Compiler Warnings Tests The Microsoft docs examples might be a good start? // C4244_level4.cpp // compile with: /W4 == actually warnings = all (warnings = errors will allow normal fail testing if it isn;t possible to check for warnings?) // AND MS extensions off? int aa; unsigned short bb; int main() { int b = 0, c = 0; short a = b + c; // C4244 bb += c; // C4244 bb = bb + c; // C4244 bb += static_cast<unsigned short>(aa); // C4244 bb = bb + static_cast<unsigned short>(aa); // OK } So are you proposing a collection of these, with versions that should compile and others that should not, for example: int main() { int b = 0, c = 0; short a = b + c; // C4244 } and another with int main() { int b = 0, c = 0; short a = static_cast<short>(b + c); // OK - NO C4244 } all run by a jamfile.v2. Or am I still misunderstanding you? Vicente has said he will think about it. I will also give it some more thought. Paul --- Paul A. Bristow Prizet Farmhouse Kendal, UK LA8 8AB +44 1539 561830, mobile +44 7714330204 pbristow@hetp.u-net.com --- Paul A. Bristow Prizet Farmhouse Kendal, UK LA8 8AB +44 1539 561830, mobile +44 7714330204 pbristow@hetp.u-net.com

Paul A. Bristow wrote:
And I'm starting a new thread for Compiler Warnings Tests
The Microsoft docs examples might be a good start?
// C4244_level4.cpp // compile with: /W4 == actually warnings = all
(warnings = errors will allow normal fail testing if it isn;t possible to check for warnings?)
// AND MS extensions off?
int aa; unsigned short bb;
int main() { int b = 0, c = 0; short a = b + c; // C4244
bb += c; // C4244 bb = bb + c; // C4244 bb += static_cast<unsigned short>(aa); // C4244 bb = bb + static_cast<unsigned short>(aa); // OK }
So are you proposing a collection of these, with versions that should compile and others that should not, for example:
int main() { int b = 0, c = 0; short a = b + c; // C4244 }
and another with
int main() { int b = 0, c = 0; short a = static_cast<short>(b + c); // OK - NO C4244 }
all run by a jamfile.v2.
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. Look at boost/libs/config tests for inspiriation. Tests would be something like: boost/libs/warnings/ test_data_truncation // this would correspond to C4244 for ms and ? for other ones // this test would be "compile-pass" // and it would contain a number of tests cases test_unused_argument test_argument_name_shadowing test_virtual_dtor_missing test_cant_create_default_construtor test_cant_create_default_assignment ... On the boost testing matrix, the first row describes the environment. To make this useful, this test should be run with the first row - environment description including the warning level. Note that I use my library_test.sh to run tests for one specific library. This creates an html test matrix on your local machine which shows all the warning emitted. The beauty of this system is that it's very easy to run the tests and create the test matrix on your local machine for just one library. Robert Ramey

Robert Ramey wrote:
Paul A. Bristow wrote:
And I'm starting a new thread for Compiler Warnings Tests
The Microsoft docs examples might be a good start?
// C4244_level4.cpp // compile with: /W4 == actually warnings = all
(warnings = errors will allow normal fail testing if it isn;t possible to check for warnings?)
// AND MS extensions off?
int aa; unsigned short bb;
int main() { int b = 0, c = 0; short a = b + c; // C4244
bb += c; // C4244 bb = bb + c; // C4244 bb += static_cast<unsigned short>(aa); // C4244 bb = bb + static_cast<unsigned short>(aa); // OK }
So are you proposing a collection of these, with versions that should compile and others that should not, for example:
int main() { int b = 0, c = 0; short a = b + c; // C4244 }
and another with
int main() { int b = 0, c = 0; short a = static_cast<short>(b + c); // OK - NO C4244 }
all run by a jamfile.v2.
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.
Look at boost/libs/config tests for inspiriation. Tests would be something like:
boost/libs/warnings/ test_data_truncation // this would correspond to C4244 for ms and ? for other ones // this test would be "compile-pass" // and it would contain a number of tests cases
test_unused_argument test_argument_name_shadowing test_virtual_dtor_missing test_cant_create_default_construtor test_cant_create_default_assignment ...
On the boost testing matrix, the first row describes the environment. To make this useful, this test should be run with the first row - environment description including the warning level.
Note that I use my library_test.sh to run tests for one specific library. This creates an html test matrix on your local machine which shows all the warning emitted. The beauty of this system is that it's very easy to run the tests and create the test matrix on your local machine for just one library.
Robert Ramey
Hi, I second the point of view that the test case shouldn't be associated with a particular compiler. But I have some comments on this. Here is how I see the compiler warning tests: 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. 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 } [Note: The following should not correspond to the bjam syntax] [ compile_fails test_data_truncation.cpp : : warnigs_as_errors=on define=BOOST_WARNING_AS_ERROR_MUST_FAIL : test_data_truncation_warning_as_errors_must_fail ] [ compile test_data_truncation.cpp : : warnigs_as_errors=on define=BOOST_WARNING_AS_ERROR_MUST_SUCCEED : test_data_truncation_warning_as_errors_must_succeed ] [ run test_data_truncation.cpp : : warnigs_as_errors=off ] The question no is how to use this test on compiler that don't warm in this case. For these compiler [ compile_fails test_data_truncation.cpp : : warnigs_as_errors=on define=BOOST_WARNING_AS_ERROR_MUST_FAIL : test_data_truncation_warning_as_errors_must_fail ] will fail as the compilation succeeds. 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: int main() { int b = 30000, c = 30000; #if defined(BOOST_WARNING_AS_ERROR_MUST_FAIL) short a = b + c; // C4244 #if "compiler don't warms# #warning "There is no issue with this compiler. warning only to make the test succeed" #endif #elif !defined(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 } Note that we need a specific file by test as we need to check the warning disappears on the different situations. I'll continue to look for a better approach. Please let me know what do you think. Best, Vicente -- View this message in context: http://old.nabble.com/Compiler-Warnings-Tests-tp26545937p26554919.html Sent from the Boost - Dev mailing list archive at Nabble.com.

Vicente Botet Escriba wrote: [Vicente, please don't overquote]
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.
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. The initialization of a2 is expected to produce no warnings in any case, so it needn't be special cased. 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. HTH, _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

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.

Vicente Botet Escriba
Stewart, Robert wrote:
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));
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 preprocessor logic I mentioned would determine whether a particular compiler produces a warning or not and that would dictate how BOOST_MUST_WARN is defined. Since each test file can test a single warning, or group of related warnings, all uses of BOOST_MUST_WARN in that translation unit will behave the same. In different tests, it can behave differently as the test and compiler require. IOW, after using the preprocessor to determine whether a given compiler produces a warning or not for *a single test*, and setting a manifest constant to indicate that expectation, the boilerplate preprocessor logic will produce a suitable definition of BOOST_MUST_WARN for use in that translation unit. In some cases, it will simply emit the supplied code. In others, it will emit the code and then something that will synthesize an appropriate test outcome. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Stewart, Robert Sent: Monday, November 30, 2009 1:26 PM To: boost@lists.boost.org Subject: Re: [boost] Compiler Warnings Tests
Vicente Botet Escriba
Stewart, Robert wrote:
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));
Either looks plausible, but I would just remind you that there are only about 20 code constructs where warnings that seem to cause trouble, so are you sure we are not making a mountain out of a molehill? If either or both produce a working example for just one type of warning, I'll do the grunt work in setting up the test for all (20 of) the rest - for my sins, since I moaned too much about warnings in the first place ;-) Paul --- Paul A. Bristow Prizet Farmhouse Kendal, UK LA8 8AB +44 1539 561830, mobile +44 7714330204 pbristow@hetp.u-net.com

Paul A. Bristow wrote:
Stewart, Robert wrote:
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));
Either looks plausible, but I would just remind you that there are only about 20 code constructs where warnings that seem to cause trouble, so are you sure we are not making a mountain out of a molehill?
If either or both produce a working example for just one type of warning, I'll do the grunt work in setting up the test for all (20 of) the rest - for my sins, since I moaned too much about warnings in the first place ;-)
You're probably right. At the least, having a standard mechanism for producing a failure when a compiler isn't expected to warn is probably desirable. Perhaps that should be captured in a reusable macro: BOOST_SYNTHESIZE_WARNING or something. Then you can use the simpler conditional compilation and avoid the extra work to create a suitable BOOST_MUST_WARN for each test. I don't think the latter is complicated, but I do wonder if we'll find it hard to insert all necessary code in the macro invocation for all cases. IOW, it is probably better to follow the conditional compilation with BOOST_SYNTHESIZE_WARNING approach. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.
participants (4)
-
Paul A. Bristow
-
Robert Ramey
-
Stewart, Robert
-
Vicente Botet Escriba