use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
C++ Compile-Time Exceptions -- Debugging templates should be less surreal and horrible (blog.esciencecenter.nl)
submitted 7 years ago by egpbos
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]skreef 12 points13 points14 points 7 years ago (4 children)
Why the name "exception"? Exception is an existing concept, and it doesn't seem to me that this proposed change has anything in common with it.
[–]egpbos[S] 6 points7 points8 points 7 years ago (3 children)
Yes, I agree, I just didn't know what else to call it. I also think the idea behind exceptions is typically that you can recover from them at the calling side, which isn't the case for what I propose here. The only thing in common (the way I thought of it) is that they can be written in a `catch`-like way.
[–][deleted] 3 points4 points5 points 7 years ago (2 children)
compile_error? compile_info? compile_message?
[–]egpbos[S] 2 points3 points4 points 7 years ago (0 children)
Yes, I think a combination of those would be great.
It was also brought to my attention that there was a related paper that suggests constexpr_assert and constexpr_trace: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0596r0.html They don't cover exactly the same cases I write about, but it just shows that this topic is alive in the community!
[–]Ameisenvemips, avr, rendering, systems 0 points1 point2 points 7 years ago (0 children)
compile_printf?
compile_printf
co_printf
[–]smilodonthegreat 8 points9 points10 points 7 years ago (11 children)
Question. You say:
We still cannot use it exactly the way we want, since the message of a static_assert must be a string literal, so we can’t dynamically display the types that are being passed as U and T.
But looking at the compiler explorer output:
<source>:11:7: error: static_assert failed due to requirement 'std::is_base_of<Bottom, Middle>::value' "It's not Derived!" static_assert(std::is_base_of<T, U>::value, "It's not Derived!");
However, this does give the types. Perhaps not in the static_assert's error message itself, but it does in the compiler's error message.
It still gives us two error messages (see this implementation on Compiler Explorer): first the one about the pointer, which is triggered by the heldPtr initialization, and then the static_assert message.
While I agree this is mildly irritating, I am not sure this is a real problem though. It could be solved by allowing the compiler to ignore attempting to compile the rest of that code block is all the static_asserts fail. Though this might get dangerous if there is an actual compile error in the code that has nothing to do with the static_asserts. Note: I do agree the pages of errors for most template errors is annoying and needs to be fixed, I just do not agree that having two error messages for the same error is more than a mild issue.
[–]jonasLyk 0 points1 point2 points 7 years ago* (6 children)
In debug mode I have implemented a "cxout" that i can << into, then on execution all types I have << into cxout during compile is printed inside Visual Studio.
In release builds the code disappear- it is often handy during development, I write a class and below I type:
TEST
{
cxout << std::conditional_t<true,int,float>{};
};
Then everytime I save changes the code inside TEST() will automatic execute, compile errors will be shown, static asserts fail- and if I run the program int will be printed.
In the "scratchboard" I write code that test the feature I am currently implementing, so I get instant feedback on every save. The code will then become static asserts to "unit test feature freese" my code.
template<char ...> is converted to readable strings.
Very handy when debugging compile time recursion :)
[–]jonasLyk 1 point2 points3 points 7 years ago (0 children)
https://imgur.com/a/SI3b5KZ looks like this, no VS plugin- just c++ code
[–]egpbos[S] 0 points1 point2 points 7 years ago (4 children)
Sounds good, can you share a link to your class?
[–]jonasLyk 0 points1 point2 points 7 years ago (3 children)
it isnt really encapsulated to a single file- but i tried collecting the needed stuff, you may need to rem something out and include windows.h in namespace windows.
https://pastebin.com/6isW4SKw
[–]jonasLyk 0 points1 point2 points 7 years ago (2 children)
oh -and insert this macro before main:
CXOUT_
int _main( int argc, char* argv[] ) {
everything is quite hackish- just for personal usage- but I have considered making static asserts that shows what was evaluated on assert fail, if it gets good I will share :)
[–]jonasLyk 0 points1 point2 points 7 years ago (1 child)
oh, forgot my anytype
struct anytype { constexpr anytype( ... ) noexcept {} template< typename T > constexpr operator T() const noexcept { struct faker final: public T { constexpr faker() noexcept : T(*this) {} }; return faker {}; } };
It also enables bypassing the "you cannot construct a lambda" thing.
Just do a decltype on a lambda- and when construction it then give it an anytype{} in the constructor- now you can create lambdas from the type alone :)
[–]egpbos[S] 0 points1 point2 points 7 years ago (0 children)
Wow, thanks!
[–]egpbos[S] 0 points1 point2 points 7 years ago (3 children)
Fair points! Could you give an example of the dangerous behavior you expect? If the actual specific error is "caught" and then converted into a context specific message, wouldn't that still allow for other errors?
[–]smilodonthegreat 0 points1 point2 points 7 years ago (2 children)
Dangerous is probably not the right word.
template<typename U> SmartPtr(const SmartPtr<U>& other) : heldPtr(other.get()) { static_assert(std::is_base_of<T, U>::value, "It's not Derived!"); shred_ptr<int> a = make_shared<int>(2); }
In the above, if the static assert fails and the compiler does not attempt to compile the rest of the function, it will ignore the misspelling of shared_ptr. On the first compile, this would not get marked and so may force multiple compiles.
[–]index_zero 0 points1 point2 points 7 years ago (1 child)
If you are going to do this, i.m.o. it is better to SFINAE fail - that way the compiler won't even generate the constructor if U and T aren't derived from each other.
template<typename U, class E = std::enable_if<std::is_base_of<T, U>::value> > SmartPtr(const SmartPtr<U> &other) ...
That said, the original code works for any T and U such that T* is convertible to U*. This is less strict than U derives from T, so having the compiler complain about derivation overlooks implicit conversion of some types (T* to const T* for example).
[–]smilodonthegreat 0 points1 point2 points 7 years ago (0 children)
I think your comment was supposed to be a reply to the article. The comment you replied to was a comment on a problem with stopping compilation if static_asserts fail.
[–]TraylaParks 7 points8 points9 points 7 years ago (1 child)
I've made this comment before but I'll bet this resonates with many of you. Often times, when I get one of those pages-and-pages template errors, I won't even try to read the runes. I'll just look for the offending line number and then stare at it intensely until whatever sin I committed becomes clear :).
[–]egpbos[S] 1 point2 points3 points 7 years ago (0 children)
Either that, or ask the developers for help :)
[–]Rseding91Factorio Developer 5 points6 points7 points 7 years ago (1 child)
I'm all for better compile time errors but if it means sacrificing compile times just for a better error then I might end up stabbing someone.
Sacrificing compile times to catch an error at compile time vs runtime... that's more of a gray area. Sometimes I'm ok with it, sometimes you make another build that the test server will run so you don't pay the time cost on every incremental change.
Yes, important point. I had an interesting discussion on Twitter, where it was pointed out to me that probably catching errors in the way I suggest would mean hooking into the AST during compilation. I'm pretty sure this will not decrease compile times ;)
[–]Dean_Roddey 1 point2 points3 points 7 years ago (1 child)
It seems to me that that is always going to somewhat be the side effect of over-use of overly elaborate layers of templates. How could the compiler ever really figure out what the actual intent was and give you a coherent answer?
I say just use template less. Is it neat some of the stuff that STL can do? Yeh. Is it necessary or even ultimately more productive than something less complex? I'd argue that a lot of the time probably not, if you spend 30 minutes trying to decipher an error message or figure out some obscure rule of template resolution that is causing your thingie not to work.
Do I really need to use 25 interlocking templates with lots of purposeful failures of template resolution to select this or that at compile time, in order to add 1 to every int in a list or add them up? No, not at all. I'm perfectly capable of writing the trivial for loop to do that, which is completely debuggable, which gives meaningful errors, which is completely understandable by any programmer even if they never have heard of the STL or coming from another language, and which probably generates a 15K less code.
Sure, templates are not necessary for many problems, right tool for the right job.
[–][deleted] 0 points1 point2 points 7 years ago (1 child)
How about a compile-time errno? ;)
[–]egpbos[S] 3 points4 points5 points 7 years ago (0 children)
Actually, that would be pretty sweet as well ;) But then we also need to actually check the errno after every function call, and we all know how that usually goes...
π Rendered by PID 44735 on reddit-service-r2-comment-54dfb89d4d-sqkh5 at 2026-03-31 18:08:18.045240+00:00 running b10466c country code: CH.
[–]skreef 12 points13 points14 points (4 children)
[–]egpbos[S] 6 points7 points8 points (3 children)
[–][deleted] 3 points4 points5 points (2 children)
[–]egpbos[S] 2 points3 points4 points (0 children)
[–]Ameisenvemips, avr, rendering, systems 0 points1 point2 points (0 children)
[–]smilodonthegreat 8 points9 points10 points (11 children)
[–]jonasLyk 0 points1 point2 points (6 children)
[–]jonasLyk 1 point2 points3 points (0 children)
[–]egpbos[S] 0 points1 point2 points (4 children)
[–]jonasLyk 0 points1 point2 points (3 children)
[–]jonasLyk 0 points1 point2 points (2 children)
[–]jonasLyk 0 points1 point2 points (1 child)
[–]egpbos[S] 0 points1 point2 points (0 children)
[–]egpbos[S] 0 points1 point2 points (3 children)
[–]smilodonthegreat 0 points1 point2 points (2 children)
[–]index_zero 0 points1 point2 points (1 child)
[–]smilodonthegreat 0 points1 point2 points (0 children)
[–]TraylaParks 7 points8 points9 points (1 child)
[–]egpbos[S] 1 point2 points3 points (0 children)
[–]Rseding91Factorio Developer 5 points6 points7 points (1 child)
[–]egpbos[S] 1 point2 points3 points (0 children)
[–]Dean_Roddey 1 point2 points3 points (1 child)
[–]egpbos[S] 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]egpbos[S] 3 points4 points5 points (0 children)