1/10/2025 at 5:29:17 PM
C syntax is already way too rich and complex.We need a C- ore µC:
No implicit cast except for literals and void* (explicit compile time/runtime casts), one loop statement (loop{}), no switch/enum/generic/_thread/typeof/etc, no integer promotion, only sized primitive types (u64 s32 f32 etc...), no anonymous code block, real compiler hard/compile time constant declaration, many operators have to go (--,++, a?b:c, etc)... and everything I am forgetting right now (the dangerous struct pack attribute...). But we need inline keywords for memory barriers, atomics for modern hardware architecture programming.
by sylware
1/10/2025 at 8:27:59 PM
There is C0, a stripped-down version of C popular in academia [1]. Great for teaching because it's conceptually simple and easy to write a compiler for. But with a couple of additions (like sized primitive types) it might match what you are imaginingby wongarsu
1/10/2025 at 6:48:55 PM
C really just needs if / else / while / and void functions. Function inputs should be in/out (const type* or type*).by glouwbug
1/10/2025 at 8:02:42 PM
So, FORTRAN IV except for the else.by bregma
1/10/2025 at 7:20:31 PM
Pre-scheme?by butterisgood
1/10/2025 at 6:43:39 PM
Does Zig fit your bill?by accelbred
1/11/2025 at 1:13:26 AM
Dunno, I should have a look though. But I have recollection of some garbage collector, wrong/right ?by sylware
1/11/2025 at 1:50:48 AM
I doubt that, zig is allocators land. Even stdlib datastructures required an allocators to be instanciated. Have a look at the selection of allocators: https://zig.guide/standard-library/allocators .by nick__m
1/11/2025 at 4:51:45 PM
I had a look, zig seems to require a runtime, even small, for basic syntax support. So it seems it is not suitable.You should be able to generate machine code without the need of any runtime, like you can with C.
by sylware
1/11/2025 at 6:51:58 PM
I'm unsure what you're referring to here -- Zig doesn't have any runtime, it doesn't even depend on libc.The only thing I can think of that you might be referring to is compiler-rt: if so, this is a thing in C too! It's just a small collection of implementations for operations the code generator wants to call into (e.g. memset, arithmetic for integers larger than CPU word size). Clang uses compiler-rt when compiling C code, and GCC's equivalent is libgcc. Nonetheless, Zig lets you disable it using `-fno-compiler-rt`, in which case you'll need to provide the relevant symbols yourself somehow.
by mlugg
1/11/2025 at 6:58:17 PM
This is not what I understood, there is some kind of flags required for pointers or something, which requires a data section for basic primitive types.by sylware
1/11/2025 at 7:27:36 PM
I'm afraid I'm not sure what you're referring to. For instance, I can build a simple Hello World in Zig using `zig build-exe`, and get a static executable, on which I can use `nm` to confirm that there aren't symbols from any kind of runtime. I can even trivially build the actual Zig compiler to a static binary.(For context, by the way, I'm on the Zig "core team"; I'm a notable contributor to the project.)
by mlugg
1/11/2025 at 9:58:32 PM
mmmmh... basically, generates machine code which only requires a stack (which could be used by code paths not written in zig), contained in memory pages with execute and read permission only. Ofc this machine code would interact with the other machine code (written in other languages) via the architecture calling convention (the ABI/C one).by sylware
1/14/2025 at 5:56:05 PM
Thats what Zig does. It compiles down to the same stuff as C. It does not have a runtime.by accelbred
1/14/2025 at 9:30:51 PM
It also has been very much trying to get rid of things like "undefined behavior".by butterisgood
1/10/2025 at 6:40:57 PM
Sooo, assembly :)by short_sells_poo
1/10/2025 at 7:16:16 PM
No. Assembly is not portable, not typed and not structured (as in structured programming).Another usecase for microC: most decompilers decompile to a custom C-like language. It pretends to be C, but in reality this is just a representation of a recovered AST that is often-but not always-a valid C code. MicroC would be a better target, because it would supposedly have less weird edge cases.
by poincaredisk
1/11/2025 at 11:04:47 AM
Hence why Macro Assemblers have existed for almost as long as raw Assembly.MASM and TASM, were already far beyond the features in K&R C, if we overlook the issue of being bound to 80x86 Assembly.
TI has some DSPs where their Assembly is basically bare bones C like, in a SSA kind of approach.
by pjmlp
1/10/2025 at 8:58:23 PM
I don't think any weird edge case is a problem when targeting C. You just do not produce such cases when emitting the code.by uecker
1/10/2025 at 8:14:03 PM
I'd argue that unsafe Rust is a better target here (although I don't know if &raw has made it into stable Rust yet, which you need for doing an address-of that doesn't have a risk of UB like & does). Rust's typesystem is less silly (there's only one multiple-types-for-same-value, namely usize), there's no implicit conversions, the core CFG primitives are a little bit richer (labeled break/continue, although those are now added in C2y), and there's a decent usable intrinsic class for common operators-not-in-C like rotations or popcount.If your goal is a simple language to compile, well, Rust won't ever fit the bill; but as a target for a decompiler, I think the unsafe subset is worth exploring.
by jcranmer
1/10/2025 at 8:28:29 PM
&raw landed in the release just before this latest one.And even before that release, there were macros the poly fill it, so you could have used those to target an earlier version.
by steveklabnik
1/10/2025 at 9:14:00 PM
Why would you target a language that is less portable and less stable?by uecker
1/10/2025 at 9:28:42 PM
For the specific question of decompiling, as noted in the GP comment, you're already forced to decompile to a not-quite-C language because C's semantics just aren't conducive to accurately representing the hardware semantics. Not that Rust doesn't have its own foibles, but I suspect its core semantics are easier to map to than C's semantics without having to resort as much to a not-quite-Rust target.It's definitely something I would like to see at least explored!
by jcranmer
1/10/2025 at 9:33:36 PM
I am pretty sure somebody will do this. My guess is that it will make basically no difference, but the end result is likely less useful...by uecker
1/11/2025 at 12:38:26 PM
dude... we say C has some syntax already too rich and complex and you bring rust on the table? please...by sylware
1/10/2025 at 7:28:59 PM
> Assembly [...] not typed and not structured (as in structured programming).That depends on the assembly language. Some have structure constructs, some are typed. Portability is out.
But if you accept a slightly higher abstraction, WebAssembly is portable, typed, and structured.
by 9rx
1/10/2025 at 8:00:02 PM
> But if you accept a slightly higher abstraction, WebAssembly is portable, typed, and structured.Does WebAssembly support AOT compilation to native binaries? I thought it was just a VM.
by PittleyDunkin
1/11/2025 at 12:13:37 AM
It does if you implement it! You can do anything if you get around to doing it.Or use an existing implement like wasmedge, I guess.
by 9rx
1/11/2025 at 1:18:59 AM
Yep, assembly... but a royalty free, brutally simple ISA...Wait... we have it... RISC-V.
But we need performant µArchitectures of all major use cases (server/desktop/mobile/etc) and that on the best silicon process.
If RISC-V is a success, no need for a µC, just go RISC-V assembly BUT... do not abuse that macro preprocessor, because if it is to move complexity from the C syntax to some macro preprocessor, that would be pointless.
by sylware
1/10/2025 at 7:20:43 PM
Sphinx C-- maybe?by Frenchgeek
1/11/2025 at 1:15:27 AM
Is that microsoft C--?by sylware
1/11/2025 at 6:37:09 PM
https://bkhome.org/archive/goosee/cmm/by Frenchgeek
1/12/2025 at 12:39:46 PM
Had a look, its syntax is already too rich: I saw "while" "switch" etc.I guess, we are looking for even simpler thas sphinx c--.
I start to wonder, if I could not express such simple C syntax using a powerful assembler macro preprocessor (like the one of fasm2). Until there is a "expression" processor, it should kind of be easier.
by sylware
1/10/2025 at 7:08:29 PM
You want assembly with some sugar.Read up on Forth languages. It's pretty much exactly what you're after.
by mystified5016
1/10/2025 at 7:14:36 PM
Forth is kind of weak dealing with value types of unknown size. For example, suppose you're writing a cross-compiler, and an address on the target machine might take one or two cells on the host machine depending on the host bitness. Now suppose you need to accept a (host-machine) cell and a target-machine address (e.g. an opcode and an immediate) and manipulate them a bit. Trivial in C, definitely possible in Forth, but supremely annoying and the elegance kind of falls apart.by mananaysiempre
1/14/2025 at 3:43:25 PM
Assembly isn't portable? Wow! You must be some type of genius! I'll start calling newspapersby mystified5016
1/15/2025 at 1:05:06 AM
Assembly language isn’t, but assemblers usually are. If you want a (cross-)assembler for 32-bit x86, you can build GNU as or Nasm on any reasonable platform with a C implementation, because, ultimately, bytes are bytes, and you can write void emitd(struct buf *buf, int opcode, uint_least32_t address);
or however it looks inside your assembler without caring what sizeof(int) is (assuming CHAR_BIT is 8). By comparison, in Forth that will be emitd ( buf op adr -- ) ( 32-bit host )
emitd ( buf op ahi alo -- ) ( 16-bit host )
depending on the bitness of where your assembler runs, even if the machine it assembles for is exactly the same in both cases. You cannot hide the platform difference behind a typedef for uint_least32_t or whatnot, unless you’re willing to drastically reshape the entirety of Forth from inside (which it does allow).
by mananaysiempre
1/11/2025 at 11:47:11 AM
endian support is like the memory barrier and atomic support, should be inline function/keyword.by sylware