9 ms·
This sort of requirement is met by compile time computations. I know C++11, D and Rust have them, and I imagine many more languages do as well. The need for thi
by scott_s 6y ago
This sort of requirement is met by compile time computations. I know C++11, D and Rust have them, and I imagine many more languages do as well. The need for this sort of thing clearly has not gone away, we're just moving away from a free-form, textual pre-processing stage.
- kenniskrag 6y agoconstexpr in c++ is pretty magic. Loops, try catch etc. is possible (https://en.cppreference.com/w/cpp/language/constexpr https://en.cppreference.com/w/cpp/language/constexpr)
- filleokus 6y agoOne of the few things I was truly amazed by when doing some C++ courses during university. Contrived OOP or extremely cumbersome string manipulation wasn't really my thing. But being able to have compile time evaluation of pretty complicated functions without using macros or anything was so cool. Actually thought about wanting it yesterday in Go
- midjji 6y agoIts truly very nice :) So much horrible preprocessor stuff goes away. Not that preprocessing cant be done right, its just that the standard C/C++ preprocessor language breaks almost every rule of a maintainable code. I love compiler sanity checks of math operations with static asserts, and stuff like compile checking for ub and cdb. constexpr int signed_int_fixed_yet(){ // compiler error return std::limits<int>::max +int(1); } tuplify<PodType>() is wonderful too. Just a shame it adds so much boilerplate though, like why couldnt every function have the same constexpr if possible property as lambdas, and is so damned slow and costly to compile. I also keep writing half of a nice interface, then running into template recursion depth, or gcc failing to compile correctly/(identically to clang). Its also still a bit too limited. Like, consider the case where everything is known compile time: int a=5; // lets say sizeof(a) =4 a<<64; // should be compile error, not ub for(int i=0;i<64;++i) a<<i; // should be compile error, // note that either line above can be removed by the compiler. Leaving a=5; template<class T, int R,int C> Matrix{ std::array<T,RC> data; // constexper // should be automatic T operator(int row, int col){ if is_constexpr_in_context(row) // now wouldnt this be nice... static_assert(row<R,""); // only if row is constexpr argument return data[rowC+col]; } }; Matrix<double,3,4> m; auto a=m(1,2) // row is known compiletime, compiler will warn, should be compile error m(a+3,0) // also known compiletime(array default init to 0), should warn, should be compile error for(int r=0;r<3;++r) for(int c=0;c<6;++c) a+=m(r,c); // oob known compiletime, should warn... Its not like this is that hard either, just transform the statements to use m.at<r,c>() and it works, so its just the compiler identifying constexpr context automatically as for lambda and replacing functions with their argument templated equivalents, and autogenerating these functions. It cant fix everything, but the number of errors people made when using such libs would massively decrease, especially since templated matrix classes are almost universally have visible definitions, and it often applies.
- kenniskrag 6y ago> Its also still a bit too limited. Like, consider the case where everything is known compile time: int a=5; // lets say sizeof(a) =4 a<<64; // should be compile error, not ub for(int i=0;i<64;++i) a<<i; // should be compile error, // note that either line above can be removed by the compiler. Leaving a=5; It is UB for signed integers. There is a lot of stuff from c inside c++ :-).
- jdc 6y agoNim too