With 0.7.11 we've reached the end of the 0.7 era. It's been a really good year for C3, improving on rough edges and expanding the stdlib.
This release is headlined by an updated matrix library. Aside from that, it’s a refinement release, bringing numerous fixes but no major changes.
Language changes¶
constdef inference through binary operations¶
constdef is often used to define masks:
In 0.7.10 inference worked through assignment but not expressions:
From 0.7.11 onwards, the inference works:
Updated @weak¶
@weak, which changes linkage, now also supports having multiple definitions of the same declaration in the same source code, allowing the non-"weak" definition to win. This allows things like changing code from this:
fn void foo() @if(env::POSIX)
{
io::printn("Works!");
}
fn void foo() @if(!env::POSIX)
{
abort("Unsupported foo()");
}
fn void foo() @if(env::POSIX)
{
io::printn("Works!");
}
fn void foo() @weak
{
abort("Unsupported foo()");
}
Warning on $$builtin use¶
Builtins (functions prefixed with $$, such as $$unreachable) are intended to be accessed through standard library macros, not used directly. They are considered internal and may change without warning.
This wasn’t previously clear, and some code ended up using them directly. The compiler will now issue a warning when such builtins are used outside the standard library.
Zero element enums forbidden¶
Before 0.7.11, the language allowed empty enums. In practice, they were not fully supported and could lead to incorrect behavior.
Given their limited usefulness and the inability to define a valid zero value, empty enums have been removed from the language.
Misc improvements¶
C3 now also detects large temporaries when creating slices on the stack.
Standard library¶
Updated Matrix library¶
The big change is the updated Matrix library. The new matrix type is column major, aligning it with most graphics and math libraries. It has also undergone quite an overhaul, with methods and functions updated and fixed. The default aliases are now based on floats rather than doubles, which fits with common usage.
The predefined aliases are:
Quat- quaternionMat2- 2x2 matrixMat3- 3x3 matrixMat4- 4x4 matrixVec2- 2d vectorVec3- 3d vectorVec4- 4d vectorRect- 2d rectangle
The matrix perspective and ortho, project and unproject functions are now right-handed [0,1].
std::mem improvements¶
std::mem::allocatoris deprecated and split intostd::core::mem::allocatorscontaining allocators andstd::core::mem::allocfor various allocation methods. This means replacing mostallocator::*calls withalloc::*, e.g.allocator::callocbecomesalloc::calloc.@unaligned_loadand@unaligned_storeare deprecated in favour ofmem::loadandmem::store, which also supports unaligned volatile load/store operations.
std::encoding improvements¶
- Serialization to and from structs using JSON is now available.
- Functions for gzip compression and decompression added.
- Support for AES encrypted Zip files
- Base32/Base64/Hex/Codepage encoding deprecated encode_buffer/decode_buffer, replacing them with
encode_intoanddecode_into.
Crypto / hashes¶
- Keccak, SHA3, Shake, CShake, kmac, Turboshake, Tuplehash and Parallelhash were added.
- The remaining Xoshiro and xoroshiro PRNG variants were added.
- Added Argon2 hash.
entropymodule for generating cryptographically secure random bytes.random::seederno longer uses temp memory.
Date / Time¶
- DateTime and DateTimeTz are now
Printableand can be used directly withprintf - DateTime now has a
to_formatmethod.
Misc improvements¶
- The backtrace has been cleaned up on Linux.
- ZString now has a hash method.
- Simple member-wise struct comparison using
member_eq. always_assertmacro, which asserts even in unsafe mode.file::last_modifiedwas added.SubProcesswas renamedProcessand refreshed with new, more streamlined, functions.- Use methods
short_name()and@short_name()to get the unqualified fault name, e.g.io::EOFbecomesEOF.
Removal of support for LLVM 17/18 and fixes for LLVM 22¶
On most platforms, the C3 compiler is linked with custom-built LLVM libraries, which reduces the need to support older versions of LLVM.
0.7.10 was incompatible with LLVM 22, which is fixed in this version.
Fully static builds of C3C for Linux¶
With 0.7.11, MUSL-based builds of the compiler are available on Linux.
Unified SDK fetching with Android support¶
0.7.10 brought automatic download of the MSVC SDK without needing external scripts. In 0.7.11, this is extended to support Android, with the goal of bringing in more targets, such as the MacOS SDK for effortless cross-compilation.
Bug fixes¶
0.7.11 brings many major and minor bug fixes, see the complete release notes for details.
Looking Forward¶
Next up will be 0.8.0. As usual, this means there will be breaking changes. The most obvious target is all the deprecated functionality, from enum Foo : const int to the old matrix library.
However, the big upcoming change is the so-called "Szmageddon": C3 will change from unsigned sizes (usz) to signed sizes by default. This will also affect type promotion rules and literal types.
Community and Contributions¶
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:¶
Stdlib: Alexandru Paniș, Book-reader, Bram Windey, Dave Akers, Disheng Su, Flanderzz, Konimarti, Manu Linares, LowByteFox, Siladi, Skunky, Technical Fowl, Zack Puhl
Compiler & toolchain: Dmitry Atamanov, Lucas Alves, Manu Linares, Nmurrell07, Rodrigo Camacho
CI/Infrastructure: Manu Linares, Mehdi Chinoune, Sisyphus1813, Zack Puhl
Change Log¶
Click for full change log
Changes / improvements¶
- Removed support for LLVM 17, 18.
- Detect large temporaries when creating slices on the stack #2665
- Search for the linker in PATH; use the builtin linker if CC missing. #2906
constdefinference through binary expressions:Foo f = Foo.AUDIO | Foo.VIDEOcan be writtenFoo f = AUDIO | VIDEO;- Fix for LLVM 22+ compatibility #2987
@weaklinkfor just affecting linkage.- Add a fully static build of
c3cfor Linux. #2949 @weaknow allows direct overriding of@weakdefinitions with a real definition.- Unified SDK fetching under
c3c fetch-sdk <target>(windows, android) and added support for automatic Android NDK (r29) download. Better progress bar. #3019 - Improved Linux backtrace readability by stripping internal panic and runtime startup frames. #3008
- Added repetition compression for deep recursive stacks in backtraces. #3008
- Added new builtins:
$$acos,$$asin,$$atan,$$cosh,$$exp10,$$sinh,$$tanand$$tanh. - Added the rest of the
xoshiroandxoroshiroPRNG variants. #3027 - Improve error when using keyword as identifier #3066
- Warn when using $$builtin functions outside of the stdlib #3065
- Zero element enums now disallowed.
Stdlib changes¶
- Add contract on
any_to_enum_ordinalandany_to_intto improve error when passed an empty any. #2977 - Add hash method for ZStrings. #2982
- Added json serialization from structs.
- Add
keccakand Keccak-based hash functions:sha3,shake,cshake,kmac,turboshake,tuplehash, andparallelhash. #2728 - Added
fault.short_nameandfault.@short_nameto get just the fault name for both run and compile time. #3002 - Compiler runtime functions extracted outside of std.
- Add the GZIP file format (RFC 1952).
- Add file::last_modified.
- Make DateTime and DateTimeTz
Printable. - Add
to_formatfunctionality for DateTime. SubProcess/process::create/process::execute_stdout_to_bufferdeprecated, replaced byProcess/process:spawn/process::run_capture_stdout.- Add support for AES-encrypted Zip files (AE-1 and AE-2 formats).
- Add
Argon2memory-hard hashing with associated tests. #2773 - Matrix type is now column major.
- Fix matrix perspective and ortho, project and unproject to be RH [0,1]
- Add vec3 methods:
rejection,project, implementunproject. - Add vector function
cubic_hermite - Deprecated
sq_magnitude,barycenter,towards,ortho_normalize,clamp_mag, uselength_sq,barycentric,move_towards,orthonormalize,clamp_lengthinstead. - Add Quaternion conversion functions to from Euler angles and axis+angle.
math::deg_to_radandmath::rad_to_degrespects the underlying type, returningfloaton afloatargument.- Added
float.to_radiansandfloat.to_degreesand the same fordouble. - Added
Quat,Mat2,Mat3andMat4,Vec2,Vec3,Vec4aliases. - Added
is_normalizedto Quaternion and floating point vectors. - Added
quaternion::from_rotationandquaternion::from_normalized_rotation - Added
Recttype. - Added
matrix::frustum. - Added
math::@absfor compile timeabs. - Make
Errnoa constdef containing all definitions. Deprecatedlibc::errnoconstants. random::seederno longer uses temp memory.- Add simple member-wise struct comparison with
member_eq. #2801 std::core::mem::allocatordeprecated and split intostd::core::mem::allocatorscontaining allocators andstd::core::mem::allocfor various allocation methods.- Add
always_assertbuiltin macro. - Add an
entropymodule to generate cryptographically-secure random bytes. #3022 - Add a builtin
TIMEOUTfault definition. #3022 - Base32, Base64, Hex and Codepage encoding deprecates
encode_bufferanddecode_buffer. Those are replaced byencode_intoanddecode_intowithdstbeing the first argument. #3055 hex::encode_bytesandhex::decode_bytesare deprecated in favour ofhex::encode_bytes_intoandhex::decode_bytes_intowhich hasdstthe first argument. #3055- Deprecation of
@unaligned_loadand@unaligned_store. Usemem::loadandmem::storeinstead.
Fixes¶
@deprecatedin function contracts would be processed twice, causing a compilation error despite being correct.- Name conflict with auto-imported std::core, but it should have lower priority #2902
- Regression: missing generic nesting check on non-types.
- Improved stringify.
- PollSubscribe was incorrectly an int instead of ushort. #2997
- SubProcessOptions.search_user_path did nothing on non-windows systems despite comment saying it should #2845
- AES implementation fixed to be constant time #2806
- Object would not properly compile on 32-bit Linux.
read_varintandwrite_varintdid not work properly for ulong and wider.io::EOF.nameofwould yield justEOFwhereas resolving it at runtime would (correctly) yieldio::EOF.$stringifywould incorrectly capture lambdas. #2986- Regression:
Stringwas not implicitly@constinit#2983 - Compiler does not propagate @noreturn through macros using short declaration syntax #3011
- Debug info emitted on
-Os#3015 - @assert_leak() would not work properly with
--safe=no#3012. - Duplicate symbols when building executables on Termux. #2984
double[<*>].maxand.minwere broken.- Incorrect codegen, crashing the compiler, when passing a
{ .xy = 1 }constant initializer vector to a function taking a vector, hitting vec->array conversion. #3035 - Folding an anon struct member at compile time would crash #3034.
- Crash in sema_compare_weak_decl when replacing a function declaration from a .c3i file in some cases #3031
- Issue with 'inline' keyword on enum and constdef #3032.
- When checking aliases
alias FOO = _BARthe compiler would incorrectly would say that_BARwasn't a constant. - Wasm32 builds crash on startup (unreachable!) due to atexit signature mismatch #3040
@nodiscard,@maydiscardand@noreturnweren't properly handled for function type declarations.$definedwith body expansion would not correctly check if parameters were the right type.mask_from_intwould miscompile on some platforms.- Overaligning structs while using
@packedwould cause incorrect lowering #3000 - Splatting a literal into a typed vaarg, e.g.
test(...(int[2]){ 88, 99 }, a: 123)could cause the compiler to crash. &some_global[0]was incorrectly considered a global constant whensome_globalwas a slice.- Taking the type of a macro identifier would give the wrong error.
- Taking the type of a
$$builtinfunction would crash the compiler. - Wrong error message when trying to take the address of a
$$builtinfunction. - Accessing a (non-existing) property on a type-call would crash the compiler.
- Crash instead of error when having two vaargs and the last one is an untyped vaarg.
- Detect recursive declaration
int[type()] type. - Compiler would not propagate error when
$$str_findor$$str_hasharguments were invalid, causing a crash. - Error on wrong expression when the slice range start is out of range.
void{}would be looked up as generic in some cases and cause a crash.- Inferring generic parameters recursively would fail to construct a valid source location and crash.
- Comparing an array of function pointers with any other type could crash rather than being an error.
- Crashing on codegen if an internal fault in if-catch is guaranteed to bypass the conditional.
- In
$foreachin some cases the elements was an untyped variable which would cause a crash. - Creating a global slice would be runtime checked for null in some cases.
@ensureand@requirecould contain rethrows, which then would crash the compiler.- Crash when using
$defined($Type)and$Typeis a typeid. - Assigning to a subscripted const like
{1, 2}[n] = 33wasn't marked as an error and resulted in a crash. - Codegen for the case when an assert always panics would cause a crash.
- Lambda check might run against a missing type definition if the function type alias was invalid.
- Missing check when doing
$foo++would crash the compiler if the variable wasn't initialized. - Incorrect handling of attribute operator symbols could crash the compiler instead of producing an error.
- Crash instead of error when the first method parameter is a vaarg.
- Fixes to UnalignedRef.
- Codegen would not pop debug location for a never-entered for loop, crashing LLVM lowering.
- Double negating a vector would cause a crash in lowering.
- Combining operator overload on a variadic method would cause a crash rather than emitting an error in some cases.
- Lambdas as default arguments were tagged with the wrong module, leading to linking issues.
- An initializer list with an optional field was incorrectly considered constant.
- Fix in ringbuffer for the case of popping at position 0.
Want To Dive Into C3?¶
Check out the documentation or download it and try it out.
Have questions? Come and chat with us on Discord.
Discuss this article on Reddit or Hacker News.