-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Added compile time testing support #3027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: devel
Are you sure you want to change the base?
Conversation
Added `CONSTEXPR_SECTION` that is used the same way as `SECTION`, `CONSTEXPR_REQUIRE` and `CONSTEXPR_REQUIRE_FALSE`.
…supports in C++20 only. Also enabled runtime execution of the constexpr section
70b5e5f to
1eb0ce4
Compare
137d923 to
b83a343
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## devel #3027 +/- ##
==========================================
+ Coverage 90.93% 91.08% +0.14%
==========================================
Files 201 204 +3
Lines 8681 8731 +50
==========================================
+ Hits 7894 7952 +58
+ Misses 787 779 -8 🚀 New features to boost your workflow:
|
b83a343 to
60cb3d3
Compare
| static_assert( | ||
| [&] // error: CONSTEXPR_SECTION failure. Check the compiler | ||
| // output to find the cause. You can make the section a | ||
| // SECTION to investigate at runtime. | ||
| { | ||
| callable(); | ||
| return true; | ||
| }(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| static_assert( | |
| [&] // error: CONSTEXPR_SECTION failure. Check the compiler | |
| // output to find the cause. You can make the section a | |
| // SECTION to investigate at runtime. | |
| { | |
| callable(); | |
| return true; | |
| }(), | |
| static_assert((callable(),true)); |
I don't like lamdbas when a simple expression can do it should be simpler fpr the compiler
if we are really pendatic we can use void() to always use builtin comma
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good suggestion, thanks. I didn't think about this, it's definitely better 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. I kept a message in the static assert to make the error clearer for the user. Even if the assert technically never fails (it's either true or unevaluable at compile time). At least compilers will spot this line and the users will see the error message in the code.
Regarding the cast to void, I considered it useless as callable is always a lambda that does not overload the comma operator.
Thanks for this suggestion !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the cast to void, I considered it useless as
callableis always a lambda that does not overload the comma operator.
You are right
| static_assert( false, "C++17 is required for CONSTEXPR_SECTION" ); \ | ||
| if ( false ) { \ | ||
| } else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the else?
couldn't it be if(false)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea here was to avoid side effects of the macro expansion. If it expands to a simple if, user can write an else right after the macro usage which should not be valid in my opinion.
It doesn't really matter here as the static assert fires. I can remove it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ZXShady fixed
Addressed @ZXShady comments
9ac5953 to
c22969c
Compare
Added compile-time testing macros
Discussion: https://discord.com/channels/415851350384181248/529055331880271884
Description
Why should I test code at compile-time ?
Testing code during compilation is the only way for ensuring the code does
not lead to undefined behavior.
This is critical to make your program safe, prevent unexpected crashes and worse
consequences of undefined behavior.
How ?
Catch2 made it easy to test code at compile-time.
The usage is pretty similar to testing at runtime:
SECTIONCONSTEXPR_SECTIONREQUIRECONSTEXPR_REQUIREREQUIRE_FALSECONSTEXPR_REQUIRE_FALSECHECKCHECK_FALSEAll code inside the
CONSTEXPR_SECTIONwill be evaluated during compilation.If any of the
CONSTEXPR_REQUIREorCONSTEXPR_REQUIRE_FALSEfails,it will cause a compilation error.
Warning
You cannot use
REQUIREorCHECKinside aCONSTEXPR_SECTION.Be careful not to mistake
CONSTEXPR_REQUIREwithSTATIC_REQUIRE.They both concern compilation-time testing, but they do not have the same
purpose.
Warning
You cannot nest
CONSTEXPR_SECTIONs or put aSECTIONinside aCONSTEXPR_SECTIONNote
The code inside the
CONSTEXPR_SECTIONis also evaluated atruntime. This way, it remains debuggable, and it contributes to the code
coverage analysis.
What can I test ?
You can test anything that can be evaluated in a
constexprfunction.This will depend on your compiler and the C++ standard you are using.
C++20, C++23 and C++26 improved a lot the support for
constexpr.Take a look at the C++ compiler support on cppreference
to see what you can use.
Debug failing compile-time tests
Investigate from the compiler output
You can check the output of your compiler to find the failing assertion.
The failing line should be highlighted somewhere. If you cannot see any
line:
CONSTEXPR_SECTIONruns only code that can be evaluatedat compile-time. This will depend on your compiler and the C++ standard you
are using.
CONSTEXPR_SECTION.The only supported macros are
CONSTEXPR_REQUIREandCONSTEXPR_REQUIRE_FALSE.compile). Reading a range outside its bounds, dereferencing an invalid pointer,
reading a variable after it has been destroyed, are widespread undefined
behaviors. They will be all caught by these tests.
Investigate at runtime
Tip
If you want to debug the code in a
CONSTEXPR_SECTION, you can simply replacethe
CONSTEXPR_SECTIONwith aSECTIONand the code will be evaluated at runtimeonly instead. Remember to come back to the
CONSTEXPR_SECTIONonce you aredone !
Compile time test report
At runtime, a
CONSTEXPR_SECTIONwill add a section in the test report. These sectionsprovide a way to see what was tested during compilation in the test report.
For instance, given the following test case:
The report would look like this: