7 ms·
Constexpr is a Platform (2020)
- catern 5y agoThe analogy is fun, but I'm not sure I agree with the author's conclusion: > a constexpr marker should be unnecessary, just like a hypothetical linux marker In fact, I'd love to have a "linux" annotation for functions which can only be called on Linux! Using the type system to manage the context in which a function can be called is a good idea, and allows safer code. The alternative is global type inference (which is slow) or runtime failures (which defeats the point).
- klodolph 5y agoI thought the author's conclusion was that constexpr annotations were necessary?
- runevault 5y agoI agree. He made a point that, if I understood I agree with, that constexpr is not necessarily as strict as it should be. Specifically that you only need ONE path to work at compile time to be able to be constexpr. I might be missing a reason this is a good idea but at least to me it seems bizarre. It would 100% be nice if code could be tagged by context in more ways than constexpr so the compiler can better tell you things like "put this behind an ifdef for Linux" etc (maybe with a compiler option to say this will only ever target one context and you don't need to check for that).
- tialaramex 5y agoIn Rust you can tag a function with arbitrary configuration parameters, it's common to write #[cfg(unix)] but you could equally write #[cfg(linux)] It's just that you're much less likely to need to say this. For example OSStr (borrowed reference to the Operating System specific string type) has #[cfg(unix)] reflecting APIs that make sense for a Unix-style string while #[cfg(windows)] wraps APIs that make sense if your operating system once thought characters are a u16. But the ordinary str and String don't have such APIs, you have to explicitly tell the language "I need this gross non-portable stuff" before you have to start using macros to get to the specific platform dependant elements. I suspect you could do a similar trick in C++ but it may not be standardised anywhere.
- pornel 5y agoMoreover, Rust is working on portability lints: https://github.com/rust-lang/rfcs/blob/master/text/1868-portability-lint.md https://github.com/rust-lang/rfcs/blob/master/text/1868-port... So that even when you only compile and test your code on Linux, you will get warnings about calling Linux-only functions from maybe-Windows functions.
- comex 5y agoFor some definition of “working on”. The RFC was accepted several years ago, but nobody has stepped forward to actually implement it.
- pjc50 5y agoYou can do that in C# : https://docs.microsoft.com/en-us/dotnet/api/system.runtime.versioning.supportedosplatformattribute?view=net-5.0 https://docs.microsoft.com/en-us/dotnet/api/system.runtime.v... (Strictly it's an attribute rather than a type, but it's enforced by the compiler given a target runtime)
- omoikane 5y agoSee also: https://github.com/keiichiw/constexpr-8cc https://github.com/keiichiw/constexpr-8cc This tool embeds a C compiler as a constexpr, so in theory you can do all the work at compile time and just output a static string at run time. But currently I am having trouble getting it to work, so it's perhaps not so glorious other than the amount of time it takes to compile.
- rkeene2 5y agoELVM [0] also has a C++14 constexpr target, also using 8cc as the frontend ! [0] https://github.com/shinh/elvm https://github.com/shinh/elvm
- nonsince 5y agoThis is the fundamental observation that the Zig language is built on, and it proves to be an extremely powerful way of understanding your system when taken to its logical extreme.
- dnautics 5y agoWhile the (2-3 paragaphs-in observation) is common between the post and zig, I wouldn't go so far as to call comptime a "platform" in zig, it is a very different class of thing than say arch/os/abi.
- tialaramex 5y agoI originally thought this essay would be about the fact that something like constexpr should appear to be the same platform as your target. This is an interesting property. For example, if I insist on writing down a 64-bit integer in memory and then staring at the individual bytes, the platform determines the layout of that structure. You don't want to know what the layout is for your compiler but for your target. Floating point maths is often tricky in this world. You expect the constexpr platform to have the same behaviour as your target, but emulating that (assuming you aren't in the trivial case of compiling on the target) can mean some pretty fearsome work that can't be justified. So, maybe the ARM CPU at runtime calculates a very slightly different value for the "constant" internal_damping_factor from the value used in constexpr functions on this x86-64 cross compiler... However it turns out I once again underestimated how far out C++ wants to go here. Shine on you crazy diamond.
- rowanG077 5y agoFloating point can be easily handled as long as the compiler says this is the way cte floats are handled irrespective of platform. It only gets harder if you must match the target platform. And even that could be pretty easily done with qemu for most platforms I'd wager.
- WalterBright 5y ago> we could imagine a future version of C++ where this [constexpr annotation] isn’t required: if we’re calling a function at compile-time, the compiler tries to execute it at compile-time. If it works, good, otherwise, it issues a diagnostic. This is how D's CTFE (Compile Time Function Execution) works. You can execute at compile time any function, and it will work as long as the source code is available to the compiler, and it doesn't access globals or do pointer monkey business. You can indeed build a program that runs completely at compiler time. Here's a compile time ray tracer in D circa 2006: http://h3.gd/posts/ctrace/ http://h3.gd/posts/ctrace/
- codetrotter 5y agoJonathan Blow’s programming language allows almost anything to execute during compilation as well. It’s neat. Here’s an old video where he demonstrated this: https://youtu.be/UTqZNujQOlA https://youtu.be/UTqZNujQOlA
- WalterBright 5y agoThat's true. His implementation also allows compile time function execution to make system calls. D disallows that in order to prevent malicious source code from being distributed and tricking people into compiling it. There is a mechanism to sent output to stdout, input can be read from a file residing on the compiler's system, and that's it. It's also why CTFE doesn't allow pointer monkey business, like coercing an integer into a pointer and dereferencing it.
- SubjectToChange 5y agoIf you're compiling malicious code, haven't you already lost? I don't see how preventing pointer manipulation at compile time (or anything else, really) improves security unless people never run the executable they compiled.
- WalterBright 5y agoPeople expect to check source code before running it. They do not expect to have to check it before compiling it. Malware works by taking advantage of peoples' expectations.
- qalmakka 5y agoWith constexpr and not consteval you can really do crazy stuff at compile time. It's super neat and it has eradicated macros everywhere in my code, except in those places where I need conditional compilation.
- jahnu 5y agoI really wonder why I'm finding very few uses of constexpr in my code. I feel like I'm missing out on something important but just can't find places where it works for me.
- qalmakka 5y agoHere's some examples: 1. Declare all your constants as constexpr. They can then be used everywhere in constexpr functions, and every time you invoke a constexpr function with constexpr arguments or literals there's a very high chance it will be executed at runtime. You can make expressions clearer and express stuff with functions, without paying the cost of the invocation. For instance, Intellisense and Clangd often show the value of very complex expressions on hover. 2. `if constexpr` is very effective to execute code conditionally in functions or lambdas with `auto` parameters, you just need to combine it with `std::same_as` or `std::is_same_v`. This is immensely useful with std::variant and std::visit, for instance.
- secondcoming 5y agoYes. Just last week I replaced a std::enable_if that need 3 functions with one function that used 'if constexpr'. I'm sure I'll find more places soon.
- jeffrallen 5y agoThis article is excellent ammunition for people who don't think C++ is good for our industry. We need fewer things to reason about while programming, not more "platforms" to reason about concurrently.
- VHRanger 5y agoPlatforms are good It's on your team culture to enforce good standards of what not to use. You can just as easily write a clusterfuck in Python (it's a huge language!) as in C++. Python just has a good overall culture of "what is pythonic" that helps this matter.
- pjmlp 5y agoPython is kind of ironic, it is C++ like in power, yet due to its BASIC like usage, gets a free pass from people not aware of its might.
- pjmlp 5y agoThose same persons certainly won't be using Java 17, C# 10, F# 5, Python 3.9,....