C3 0.8.3 Feature flags

Lobsters Hottest 工具

摘要

C3 0.8.3 introduces the @feat attribute, a new mechanism for top-level conditional compilation, replacing older @if usage outside generics. The compiler now provides built-in feature flags like WIN32 and LINUX, improving compile-time ordering and IDE support.

<p><a href="https://lobste.rs/s/e9v9qi/c3_0_8_3_feature_flags">Comments</a></p>
查看原文
查看缓存全文

缓存时间: 2026/08/13 19:22

# C3 0.8.3 Feature flags Source: [https://c3-lang.org/blog/c3_0_8_3_feature_flags/](https://c3-lang.org/blog/c3_0_8_3_feature_flags/) [https://github.com/c3lang/c3-web/edit/main/docs/blog/posts/c3_0_8_3_feature_flags.md](https://github.com/c3lang/c3-web/edit/main/docs/blog/posts/c3_0_8_3_feature_flags.md)C3 0\.8\.3 is now available\. The most notable change is the addition of the`@feat`attribute, which will be the new way to do top\-level conditional compilation\. ## Language changes & improvements[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#language-changes-improvements) ### @feat[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#feat) This release adds the`@feat`attribute, which is replacing the older`@if`usage on non\-generic top\-level declarations\. This attribute is essentially the same as`@if\($feature\(\.\.\.\)\)`before 0\.8\.3, but top\-level`@if`is now getting phased out except for use in generics\. #### The problem with`@if`[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#the-problem-with-if) Before`@if`we had`$if`on the top level, mirroring C's`\#if`and`\#ifdef`\. However, this gave very little information for the compiler when someone tried to use a declaration guarded by`$if`\. So`@if`was introduced to give more granular support and to make it easier for IDEs to figure out "go\-to definition" style functionality\. Unfortunately,`@if`still had the problem of`$if`, which is that its argument could be any arbitrary compile time constant expression\. But what happens if we use something like`@if\(Foo::methods\.len == 3\)`? Well, if the compiler hasn't yet reached a stage where`Foo`is analysed, its analysis is now forced\. Furthermore, even if`Foo`is analysed, methods might not be registered yet, giving subtly wrong answers\. Because C3 runs in multiple passes, there is no canonical ordering of which thing to analyse first, so it was quite unpredictable\. Even though refinements were constantly made to the ordering, the underlying flaw was unsolvable\. #### The insight[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#the-insight) Surveying the use of`@if`they roughly fell into one of three categories: 1. Conditionally include depending on compilation target, e\.g\.`@if\(env::WIN32\)` 2. Include "if no other implementation is found", e\.g\.`@if\(\!$defined\(String\)\)`\. 3. Conditionally add functionality depending on generic type, e\.g\.`@if\($defined\(\(Type\)\{\} \+ \(Type\)\{\}\)\)` Of these, the \(3\) didn't pose a problem in most cases, because in general it happened fairly late\. In the case of \(2\), this was now mostly covered by the new behaviour of`@weak`\(introduced in 0\.7\.11\)\. So what about`@if\(env::WIN32\)`? This was almost completely confined to the`std::core::env`module, which would define constants and derived constants based on compiler builtins, and all of those cases could actually be directly passed in by the compiler\. #### Introducing @feat[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#introducing-feat) As previously mentioned,`@feat`is essentially`$if\($feature\(\.\.\.\)\)`but to make this work, the compiler now provides many feature flags built\-in, such as`WIN32`,`LINUX`,`BIG\_ENDIAN`etc\. In general any use of`env::CONSTANT`has a`@feat\(CONSTANT\)`counterpart\. This solves the ordering problem because all these constants are known before declarations are registered, so any symbols with`@feat`can be filtered early\. This is not only beneficial for the compiler – LSPs and editors can take advantage of this and accurately determine what's available at compile time\. In more detail,`@feat`may take multiple constants, in which case it is satisfied on any match: ``` fn void foo() @feat(WIN32, MACOS) // available on WIN32 and MACOS {} ``` It's also possible to use`\|`instead: ``` fn void foo() @feat(WIN32 | MACOS) // alternative syntax {} ``` `\!`may be used to negate a feature: ``` fn void foo() @feat(!WIN32) // available on anything other than WIN32 {} ``` Multiple`@feat`means all must be satisfied: ``` fn void foo() @feat(MACOS) @feat(AARCH64) // only on Aarch64 MacOS {} ``` It's possible to use`&`as an alternative: ``` fn void foo() @feat(MACOS & AARCH64) // only on Aarch64 MacOS {} ``` More complex expressions using`\|``&`and`\!`are allowed: ``` fn void foo() @feat((MACOS & AARCH64) | !LIBC) // On Aarch64 MacOS or not with libc {} ``` Together with this the`$feature`function has been renamed`$feat`\(`$feature`is now deprecated and will be removed in 0\.9\.0\)\. ### Possible keyword changes[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#possible-keyword-changes) 0\.7\.0 introduced the family of "\-def" keywords:`constdef`,`typedef`,`faultdef`and`attrdef`\. After evaluating this for a little over a year, there has been some doubt whether these are really good enough\. For this reason 0\.8\.3 introduces experimental aliases for each: - `constdef`\-\>`constset`,`cenum` - `typedef`\-\>`distinct` - `faultdef`\-\>`faultconst`,`faultset`,`excuse` - `attrdef`\-\>`attrgroup`,`attrmacro` These are considered*experimental*, meaning that there is no stability guarantee\. Versions 0\.8\.4 and onwards are free to remove these aliases\. Please take time to try them out and offer feedback on them\. ### Fetching MacOS[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#fetching-macos) Previously, automated fetching of the Windows SDK was added\. This version adds SDK fetching for MacOS as well, allowing completely effortless cross\-compilation to MacOS from any other platform\. ### Windows Aarch64 support[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#windows-aarch64-support) With this version the C3 compiler finally supports Aarch64 as a Windows target\. ## Standard Library Updates[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#standard-library-updates) ### Regex[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#regex) With this release, C3 finally has regex support\. Please note that the API is considered experimental and may change in a later 0\.8\.x version\. ### Other changes[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#other-changes) JSON/object unmarshaling is now available through`json::unmarshal`,`object::unmarshal`, and related functions\.`json::temp\_load`is deprecated in favor of`json::tload`\. Geometry code should note one behavior change:`Rect\.contains\_point`is now exclusive on the maximum edge\. A new`Bounds`type has also been added for rectangular regions represented by`min`and`max`, with operations inclusive along the boundary edge\. `LinkedList`and`Deque`now have a`prepend`method,`FixedList`has`is\_full\(\)`, and ranges gained`range::upto`,`range::inclusive`,`range::exclusive`,`Range\.to\_array`, and`ExclusiveRange\.to\_array`\. Other useful additions include`io::read\_buffer`and comparison operators for`DateTime`\. Finally, the tracking allocator is now able to track cross\-thread allocation\. ## Fixes[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#fixes) This release fixes a wide range of correctness issues, including generics, compile\-time execution, JSON parsing, IO streams, compression, networking, AES CTR, RISC\-V ABI handling, doc generation, and several compiler crashes\. Notable fixes include: - Generic functions and values now correctly require a prefix\. - The arena allocator no longer errors in safe mode when freeing the last memory while the arena is full\. - `LinkedList\.push\_front\_all`now preserves the expected order\. - `BitSet\.len`now reports the bit set length instead of the underlying type size\. - RFC 3339 formatting now emits the correct value for microseconds\. - Timed`tcp::connect`now returns the real result instead of always failing with`io::GENERAL\_ERROR`\. - Generic methods are no longer checked before their generic type is fully registered\. - `\_erff`now invokes C`erff`instead of`erf`\. - AES CTR no longer loses sync for data whose size is not a multiple of 16\. - JSON no longer accepts`\\v`as whitespace\. - JSONC parsing no longer loops indefinitely on unterminated comments\. - `io::read\_all`now handles split data\. - `Scanner`now handles chunked data correctly\. - `Gzip`readers can now handle streams without seek support\. - `io::printf\("%3d", 1\)`now returns the correct printed length\. - RISC\-V structs with mixed floating\-point and integer fields are now passed and returned by value correctly\. Doc generation also received several fixes:`attrdef`declarations and docs are emitted,`alias`doc comments are included,`@return`contracts are rendered,`compiler\_rt`is excluded when`\-\-emit\-stdlib=no`, and empty JSON fields are omitted for slimmer output\. ## Thank yous[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#thank-yous) Again, this release wouldn't have been possible without the C3 community\. I'd like to extend a deep thank you to all who have contributed, both through filed issues, PRs and just plain discussions\. ### PR contributors for this release[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#pr-contributors-for-this-release) **Stdlib:**cmann1, Darvisim, hchac, Lado, Manu Linares, Omar Alani **Compiler & toolchain:**Darvisim, Fernando López Guevara, Lado, LowByteFox, Manu Linares, **CI/Infrastructure:**LowByteFox, Manu Linares, ttambow ### Change Log[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#change-log) Click for full change log### Changes / improvements[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#changes-improvements) - Windows aarch64 is now supported\. - Tracking allocator can now accept cross\-thread allocations\. - Filter test backtraces \#3368 - Improved GDB compatibility for macros\. - Fail when "emcc" is unavailable instead of falling back to the built\-in wasm linker\. - Support fetching MacSDK for easy cross compilation\. - Add`@feat`attribute, deprecate`@if`on non\-generic top level declarations\. - Add`$feat`compile time function\.`$feature`is deprecated and replaced by`$feat`\. - Experimental support for`constset`,`cenum`,`faultconst`,`faultset`,`excuse`,`attrgroup`,`attrmacro`,`distinct`\. - Defer resolution of typedef alignment and generics, allowing more recursive definitions\. - Improve error message on multiple <\> in a row\. \#2971 - Add the`lgdt`and`lidt`instructions to x86 inline assembly\. ### Stdlib changes[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#stdlib-changes) - LinkedList and Deque added a`prepend`method\. - Added`FixedList\.is\_full\(\)`method - `Rect\.contains\_point`is now exclusive on the maximum edge\. - Add`Bounds`\- a rectangular region stored as a`min`and`max`value, with all operations being inclusive along the boundary edge\. - Experimental regex support\. - Improved RFC 3986 compatibility\. - JSON unmarshaling support,`json::unmarshal`and family\. - Object unmarshaling support,`object::unmarshal`and family\. - `json::temp\_load`deprecated in favour of`json::tload`\. - `Object::is\_map`now returns true for empty objects\. - Add`range::upto`,`range::inclusive`and`range::exclusive`macros\. - Add`io::read\_buffer`\. - `DateTime`enable comparison operators\. - Add`Range\.to\_array`and`ExclusiveRange\.to\_array`methods\. ### Fixes[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#fixes_1) - Generic functions and values incorrectly would not require a prefix\. \#3374 - Arena allocator would error in safe mode when freeing the last memory and the arena was full\. \#3378 - LinkedList`push\_front\_all`was appending in the wrong order\. - `BitSet\.len`would yield the size of the underlying type, not the length\. - RFC3339 formatting would yield incorrect value for microseconds\. - `\-\-obj`will always retain the object files\. \#3380 - ThreadGroup with function returning`void`was broken\. - Timed`tcp::connect`always failed with`io::GENERAL\_ERROR`instead of the real result\. - Compile time struct with zeroed union member access causes compiler error \#3382\. - Generic methods checked before the generic type is fully registered\. - Math function`\_erff`invoked C`erf`function instead of`erff`function \#3391 - Defining local constants inside a macro causes it to fail to @const fold\. \#3397 - AES CTR would lose sync on data not multiples of 16\. - In some cases, on macros rethrowing optional values codegen could fail\. - Json accepted incorrectly accepted`\\v`as whitespace\. - JSONC parsing on unterminated comments would loop indefinitely\. - ZII array constdef would cause an assert\. \#3411 - Calling a constant void macro inside a macro stops it from being constant\. \#3410 - Using io::struct\_to\_format with`$force\_dump = true`failed to compile\. - `$foo \+= 1`would not do a copy, leading to incorrect update of`$foo`\. \#3400 - `foreach \(foo::Type t : x\)`would not parse properly\. \#3423 - Docgen improvements and fixes: emit`attrdef`declarations/docs, include`alias`doc comments, render`@return`contracts, exclude`compiler\_rt`when`\-\-emit\-stdlib=no`, and omit empty JSON fields for slimmer output \#3422\. - Several uses of InStream didn't properly handle io::EOF\. - Fixes to memory handling during zip loading\. - Multireader reading after a final empty read would crash\. - RISC\-V structs with mixed FP and integer fields were corrupted when passed or returned by value\. \#3428 - `io::read\_all`didn't handle split data\. - `Scanner`would not correctly handle chunked data\. - `Gzip`reader couldn't handle a stream without seek\. - `io::printf\("%3d", 1\)`would return the wrong printed length\. \#3432 - Crash when using ternary operator with vector type and inline constdef \#3433 - Crash on assign\-op to compile\-time subscript with non\-const result \#3419 ### Want To Dive Into C3?[¶](https://c3-lang.org/blog/c3_0_8_3_feature_flags/#want-to-dive-into-c3) Check out the[documentation](https://c3-lang.org/getting-started/introduction/)or[download it and try it out](https://c3-lang.org/getting-started/prebuilt-binaries/)\. Have questions? Come and chat with us on[Discord](https://discord.gg/qN76R87)\.

相似文章

C3 0.8.2:小幅改进

Hacker News Top

C3 0.8.2 是 C3 编程语言的一个小幅更新,增加了可复用的库目标模板、泛型反射、位结构属性、新的 @param 选项,并修复了多个 bug。

关于C扩展、可移植性和替代编译器

Lobsters Hottest

本文讨论了编写可移植C代码的实际挑战,这些挑战源于对非标准编译器扩展和glibc条件头文件的依赖,并通过构建C编译器的示例进行说明。

QBE - 编译器后端:版本 1.3

Lobsters Hottest

QBE 1.3 是一个重要的编译器后端版本,新增了 7000 行代码,引入了一种新的 IL 匹配算法,针对 coremark 基准测试进行了优化(性能从 gcc -O2 的 40% 提升到超过 63%),支持 Windows ABI 和位置无关代码生成。

EDG C/C++ 编译器项目

Lobsters Hottest

EDG 已将其著名的 C/C++ 编译器前端开源,包括与 Clang、GCC 和 MSVC 的解析兼容性、一个生成 C/C++ 代码的后端、一个预链接器,以及面向开发者和 AI 智能体的大量文档。

为C预处理器增添乐趣的扩展

Hacker News Top

作者介绍了在其DrC C2Y编译器项目中为C预处理器添加的有趣扩展,包括__print()/__where()等调试内建函数,以及用于转换参数列表的函数式__map()宏。