C3 0.7.2 - Quality Of Life
Unlike 0.7.1, 0.7.2 is not about big new features, instead it is laser focused on adding quality of life improvements, which are backwards compatible with other 0.7 releases.
Compile time additions¶
:::note[Note on compile time] C3 has visual differentiation between compile time and runtime code, to make it explicit when the code will be run.
Compile time code uses $if condition: ... $endif for conditional logic. Learn more about macros and compile time evaluation. :::
Simplifying compile time evaluated code¶
Setting a variable at compile time can now be simplified using compile time logical or ||| and compile time logical and &&& with a variable right hand expression.
The original code to set a variable at compile time:
Now this compile time variable can be set with compile time logical or ||| compactly as:
You can also use compile time logical and &&& in a similar way.
Compile time random: @rnd¶
Sometimes it can be useful to create unique ids at compile time. This is now possible with the @rnd macro.
Compile time ceil: math::@ceil¶
It is somewhat hard to write a good compile time ceil function, so 0.7.2 adds a builtin which is accessible using the math::@ceil macro.
General additions¶
Set the run directory¶
To make c3c run and c3c compile-run more convenient, it's now possible to use --run-dir (or the project setting run-dir) to set the director from which the compiler runs the resulting binary.
Limits to SIMD sizes¶
Limitations of vectors are sometimes misunderstood, they will cause code bloat if used for large vectors. For this reason a max vector size has been introduced. By default this is 4096 bits, so basically the size of double[<64>]. It is possible to increase this using --max-vector-size as needed. (As a comparison, the biggest SIMD vectors on x64 is 512 bits, so such a 4096 bit vector would be represented by 8 registers).
has_tagof works on builtin types¶
While has_tagof will always return false on builtin types, this change nonetheless simplifies writing compile time code involving tags.
Allow recursive generic modules¶
To simplify generic module resolution it was not possible to recursively generate generic module. This restriction has been lifted in 0.7.1.
Deprecations¶
Bitsize suffix deprecations¶
The bitsize suffixes are deprecated, so rather than writing 23u64 use the C style 23UL instead. u128 and i128 suffixes are replaced by ULL and LL suffixes.
Finally, the d suffix for doubles have been added as a complement to f.
Compile time reflection deprecations¶
MyEnum.elements have been deprecated. Use MyEnum.len instead. SomeFn.params have been deprecated. Use SomeFn.paramsof instead.
Deprecation for old @param docs¶
By 0.7.1 the declaration style @param foo "abc" would be allowed rather than @param foo : "abc". This was by accident. It's now properly deprecated.
Generic faults are not allowed¶
Creating faults that are parameterized is usually a mistake and should not have been allowed. It's been completely removed in 0.7.2 as it was classified as a bug.
This is no longer allowed:
Faults should be defined in a non-generic module, such as a parent module or sub-module instead.
Fixes¶
This release contains about 30 different fixes, most of them newly discovered and not regressions.
They range from fixes to advanced generic types to stdlib bugs.
Stdlib updates¶
Currently a new version of the matrix library is incubating, and while it didn't make it for the 0.7.2 release, I hope it can be included by 0.7.4 and contributions are welcome!
Optimized String -> ZString conversions¶
:::note[Note On Strings] Default C3 string: typedef String = inline char[];
C compatible, null terminated: typedef ZString = inline char*;
Learn more about strings. :::
Sometimes a String is already pointing to a valid ZString, so no copy is needed. To check this, String gets two new methods .is_zstr to check if the String is also zero terminated, and .quick_zstr which will create a temp ZString if needed, but otherwise use the String.
std::ascii moves into std::core¶
std::ascii moved into std::core::ascii. Old _m variants are deprecated, as is uint methods.
Better String tokenization¶
It's now possible to further customize tokenization, to ignore empty elements in the middle (or not), ignore any last empty elements at the end (or not). This introduces .tokenize_all which replaces the now deprecated .splitter method.
Count and replace¶
String further gets some conveniences: .count to count the number of instances of a string within the string and replace / treplace to return a new String with a substring replaced. This functionality was already in DString, but was now added to String as well.
Operator overloads for std::time and Maybe¶
Duration * Int, Clock - Clock and DateTime + Duration overloads were added for manipulating time.
For Maybe, the == operator is available when the inner type is equatable.
Subprocess improvements¶
Subprocess added an inherit_stdio option to inherit the parent's stdin, stdout, and stderr instead of creating pipes.
Change Log¶
Click for full change log
Changes / improvements¶
- Better default assert messages when no message is specified #2122
- Add
--run-dir, to specify directory for running executable usingcompile-runandrun#2121. - Add
run-dirto project.json. - Add
quietto project.json. - Deprecate uXX and iXX bit suffixes.
- Add experimental LL / ULL suffixes for int128 and uint128 literals.
- Allow the right hand side of
|||and&&&be runtime values. - Added
@rnd()compile time random function (using the$$rnd()builtin). #2078 - Add
math::@ceil()compile time ceil function. #2134 - Improve error message when using keywords as functions/macros/variables #2133.
- Deprecate
MyEnum.elements. - Deprecate
SomeFn.params. - Improve error message when encountering recursively defined structs. #2146
- Limit vector max size, default is 4096 bits, but may be increased using --max-vector-size.
- Allow the use of
has_tagofon builtin types. @jumpnow included in--list-attributes#2155.- Add
$$matrix_muland$$matrix_transposebuiltins. - Add
das floating point suffix fordoubletypes. - Deprecate
f32,f64andf128suffixes. - Allow recursive generic modules.
- Add deprecation for
@param foo "abc". - Add
--header-outputandheader-outputoptions for controlling header output folder. - Generic faults is disallowed.
Fixes¶
- Assert triggered when casting from
int[2]touint[2]#2115 - Assert when a macro with compile time value is discarded, e.g.
foo();wherefoo()returns an untyped list. #2117 - Fix stringify for compound initializers #2120.
- Fix No index OOB check for
[:^n]#2123. - Fix regression in Time diff due to operator overloading #2124.
- attrdef with any invalid name causes compiler assert #2128.
- Correctly error on
@attrdef Foo = ;. - Contract on trying to use Object without initializing it.
- Variable aliases of aliases would not resolve correctly. #2131
- Variable aliases could not be assigned to.
- Some folding was missing in binary op compile time resolution #2135.
- Defining an enum like
ABC = { 1 2 }was accidentally allowed. - Using a non-const as the end range for a bitstruct would trigger an assert.
- Incorrect parsing of ad hoc generic types, like
Foo{int}****#2140. - $define did not correctly handle generic types #2140.
- Incorrect parsing of call attributes #2144.
- Error when using named argument on trailing macro body expansion #2139.
- Designated const initializers with
{}would overwrite the parent field. - Empty default case in @jump switch does not fallthrough #2147.
&&&was accidentally available as a valid prefix operator.- Missing error on default values for body with default arguments #2148.
--pathdoes not interact correctly with relative path arguments #2149.- Add missing
@noreturntoos::exit. - Implicit casting from struct to interface failure for inheriting interfaces #2151.
- Distinct types could not be used with tagof #2152.
$$sat_mulwas missing.forwith incorrectvardeclaration caused crash #2154.- Check pointer/slice/etc on
[out]and¶ms. #2156. - Compiler didn't check foreach over flexible array member, and folding a flexible array member was allowed #2164.
- Too strict project view #2163.
- Bug using
#fooarguments with$defined#2173 - Incorrect ensure on String.split.
- Removed the naive check for compile time modification, which fixes #1997 but regresses in detection.
Stdlib changes¶
- Added
String.quick_ztrandString.is_zstr - std::ascii moved into std::core::ascii. Old _m variants are deprecated, as is uint methods.
- Add
String.tokenize_allto replace the now deprecatedString.splitter - Add
String.countto count the number of instances of a string. - Add
String.replaceandString.treplaceto replace substrings within a string. - Add
Duration * IntandClock - Clockoverload. - Add
DateTime + Durationoverloads. - Add
Maybe.equalsand respective==operator when the inner type is equatable. - Add
inherit_stdiooption toSubProcessOptionsto inherit parent's stdin, stdout, and stderr instead of creating pipes. #2012 - Remove superfluous
cleanupparameter inos::exitandos::fastexit. - Add
extern fn ioctl(CInt fd, ulong request, ...)binding to libc;
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.