Earlier quoted context omitted.
You're correct that 4 - 5 isn't undefined in C . But there's a good reason that Rust, for example, chooses not to make its built in integer types (either signed or unsigned) wrap on overflow. Wrapping is very easy for a typical processor to implement but in most cases overflow is a mistake, so you want to report it not silently give the wrapping answer instead when the programmer apparently hasn't considered overflow…
what i'm arguing is that c compilers exist primarily to support the base of existing c code and to run it correctly and with adequate performance, not out of some unhinged notion of 'competitiveness' or to entice people into writing new programs in it that is, i do think it's acceptable to have code that's harder to write and with worse performance, but not because of some hypothetical; rather, it's because that's ho…
Two types of C programmers
201–210 of 225 posts
Re: Two types of C programmers
#202Earlier quoted context omitted.
no, that is not what i mean to say at scale, it is not possible for humans to hand-write C programs that are free of segmentation fault class errors this is not controversial or in any way arguable
Sel4 would like to have a word. Inb4 you move the goalposts for "at scale". This is an operating system with capability-based access control which is not something that most operating systems even have. Also the cryptographic constraints are part of the proof system.
Re: Two types of C programmers
#203Earlier quoted context omitted.
Wat. The Zig compiler is finite and deterministic, yes, but that's not the problem. The problem is that user code is not finite nor deterministic. Even worse, Zig's compiler may be deterministic and finite, but the language is not, by far. In fact, the language is one of the most infinite languages in existence because just the type system is uncomputable! [1] (In this context, the word "undecidable" used by that sou…
> If the type system is uncomputable, then the type system will never be able to resolve all uses of function pointers everywhere. Can you elaborate on what you mean here, and the problems this might cause? Do you mean that some function pointers cannot be resolved to concrete functions? Or that the process of evaluating comptime may be infinite? Or some other problem where the compiler can't determine whether a func…
All of the above, actually.
Turing-completeness and the uncomputability thereof are widespread, easy to build, hard to keep away, and affects everything that might happen at runtime.
A list of things that can happen is infinite, but that list absolutely includes:
* Whether a particular function pointer resolves to certain functions,
* Whether evaluating the comptime portion of a Zig program will take forever,
* Whether the compiler fails to exclude a particular function from being used as a function pointer at a particular place.
Turing-completeness is a wildly powerful property, but that power is not free; the inability to figure out what might happen in a program is only just the biggest and most apparent cost.
The problems this might cause can be summarized like this: you can never know what a program will do for a given set of inputs until you run the program on those inputs, and even then, you might never know if the program never halts.
Does that make sense?
Re: Two types of C programmers
#204Earlier quoted context omitted.
I disagree that enjoying C automatically means you will like Rust. If you are obsessed with safety, Rust will be a nice solution. But Rust is a much more complex language than C, which will turn many C programmers away.
But its not really. Sure it seems so when you start. K&R and away you go, that programming is a lot easier than writing rust sure. But unless you are writing for just yourself, no current C software get developed that way. You need to understand C standard, that is quite complex and you need to understand it in detail because of undefined behavior (and of course how your compiler interprets it and sometimes fight wit…
With Rust, you have to think very differently about how to e.g. structure your data to make the borrow checker happy in many cases. This doesn't really translate to anything similar in other mainstream languages; it's a whole new skill that has to be learned.
Re: Two types of C programmers
#205I'm old enough to be in both camps. After years of toodling around in a variety of BASIC languages, I took a class on C. For the first time, I went from a vague text-to-result association to a clear picture of machine and its inner workings*. I then learned C++ and Java which were both hot garbage at the time, and a variety of scripting languages. The scripting langues are great for high productivity and mediocre per…
If you don't mind me asking, how does Zig get in the way? My own gut feel is that it's the only real "better C" out of the present crop of alternatives.
Re: Two types of C programmers
#206Earlier quoted context omitted.
Wat. The Zig compiler is finite and deterministic, yes, but that's not the problem. The problem is that user code is not finite nor deterministic. Even worse, Zig's compiler may be deterministic and finite, but the language is not, by far. In fact, the language is one of the most infinite languages in existence because just the type system is uncomputable! [1] (In this context, the word "undecidable" used by that sou…
> If you don't believe me, ask the Zig team how they plan to solve this problem. Don't ask them if they plan to solve it; ask them how. The Zig compiler has a counter that describes the maximum allowed amount of branching that the compiler can do while evaluating comptime code. The counter can be manually set to a higher value but all compilations will eventually fail if your comptime logic is too loopy. In practice…
Okay, here's a solution. It's already implemented. Nice.
Now let me destroy it.
You said those compilations "fail"; I presume there's an error that kicks in.
In that case, then some valid Zig programs will be rejected, but your type system is now not technically Turing-complete. It's also less powerful; there are going to be things that Zig's type system cannot express.
But wait; that's a user-defined setting? This means that either users will increase that setting when they need to and run into the same problem, or follow your guideline:
> In practice the guideline is to not overuse comptime and instead create a dedicated build step for things like creating pre-computed value tables.
It sounds like a dedicated build step would be the better option than comptime, to be honest.
Also, if you step out to dedicated build steps, then the compiler no longer has complete visibility into that code when analyzing. At that point, the Halting Problem applies again.
Also, what do you do if a user needs to pass a function pointer to a C function? I presume they must use a sync function? If so, that seems like a direct application of the function colors definition; some functions are unusable in certain places. If not, I'd be interested in what Zig does there.
Re: Two types of C programmers
#207C with libdispatch and clang blocks is the most fun I’ve had programming in quite some time! Here’s a web framework (complete with ORM) modeled on ExpressJS written in C: https://github.com/williamcotton/express-c The finished product is There’s also a lot of examples of the (basically required) support tooling like Valgrind, AdSan, etc. Check it out!
Carmack said low level programming is good for the soul, he's right. C is a fun programming language, don't even know why. Freestanding C with no standard library is the most fun I've had programming ever . I'd like to share my project as well: a Lisp interpreter written in freestanding C. https://github.com/lone-lang/lone
Re: Two types of C programmers
#208Earlier quoted context omitted.
i have written a fair bit of code using the windows and posix APIs, and they are OK - what features of these, often written by talented programmers, do you despise so much?
To pick the same example from both, I hate both fork() and CreateProcess(). Microsoft wrote "A fork() in the Road" [1] describing the problems with fork(), and they are right: fork() is too simple, it doesn't scale, it is inefficient, and error handling becomes next to impossible. (In my code, I have the child process return exit codes from 255 on down for error handling. It assumes, probably wrongly but right enough…
var process = new Process();
process.StartInfo.FileName = "foo.exe"
...
process.Start();Re: Two types of C programmers
#209Earlier quoted context omitted.
How do you feel about Rust?
I was really positive on Rust for at least five years. But several experiences have led me to reconsider this position, most notably the difficulty using arena allocation: https://blog.reverberate.org/2021/12/19/arenas-and-rust.html This is one of the things that endears me to Zig: passing an explicit allocator around is a very common idiom in the language.
Re: Two types of C programmers
#210Earlier quoted context omitted.
what i'm arguing is that c compilers exist primarily to support the base of existing c code and to run it correctly and with adequate performance, not out of some unhinged notion of 'competitiveness' or to entice people into writing new programs in it that is, i do think it's acceptable to have code that's harder to write and with worse performance, but not because of some hypothetical; rather, it's because that's ho…
That is an interesting point. I wonder if it would be feasible to go over every little bit of UB in the Standard and see if it could instead be well-defined in a way that would be compatible with most existing C code out in the wild. How much perf overhead that would actually be? And is there a way to quantify how many exploits that would have prevented?
https://blog.regehr.org/archives/1287
basically it seems feasible but it's going to be a lot of effort
also of course any semantics change will introduce some new exploits, but doing that once seems preferable to doing it every year