News for hackers. Stuff that matters.
Re:Why Is SQLite Coded in C? (2017) by jerf on Wednesday March 14, 2018 @12:42PM (#16586038)
I've commented several times before that I consider "C" and "C with analysis backing" to be in practice two different languages. SQLite is the latter: https://sqlite.org/testing.html

Writing SQLite in "plain C" without all that would, well, simply not work.

I agree that "C with analysis backing" is the best language for SQLite right now. However, it should not be used as an example of "How C is a great language for programming in" unless you are also planning on skillfully using a very significant subset of the tools listed in that document. SQLite doesn't prove C is great; it demonstrates how much additional scaffolding is necessary to wrap around C to get that level of quality, and given the quantity and diversity of tools we are talking about, it is not particularly complimentary to "plain C".

Re:Why Is SQLite Coded in C? (2017) by pcwalton on Wednesday March 14, 2018 @12:52PM (#16586157)
I agree. SQLite gets away with using C because it literally uses military-grade levels of verification. As John Regehr pointed out, SQLite is quite possibly the only piece of software that goes to that level of validation and testing without being required to by law.

It's not just a matter of skill, either. The cost in terms of money and time needed to develop software in that way is completely impractical in almost any commercial scenario. Aside from some very specific situations, it's not an economically viable way to produce software.

Re:Why Is SQLite Coded in C? (2017) by bsenftner on Wednesday March 14, 2018 @02:06PM (#16586897)
it is not economically viable for entertainment or disposable "apps", but extremely required for any serious, mission critical software. Seriously, the comments here betray how many people are in disposable software careers.
Re:Why Is SQLite Coded in C? (2017) by pcwalton on Wednesday March 14, 2018 @02:17PM (#16587007)
The comments here betray how much of the software economy depends on developer productivity. The fact is that SQLite style verification is not practical for almost any software, very much including "mission-critical" software.
Re:Why Is SQLite Coded in C? (2017) by phaer on Wednesday March 14, 2018 @05:05PM (#16588291)
Yes, but look how much of the software economy's infrastructure* depends on underfunded products. OpenSSH, GnuPG and OpenSSL are just 3 projects which are installed on pretty much every Linux server on the internet, including the servers of billion-dollar-businesses. It got a lot better in recent years, but still: Quite a few economically viable software companies just depend on free labor for mission-critical software product which take a lot of resources to become solid.

And while we are at it: http://www.openbsdfoundation.org https://gnupg.org/donate/ https://www.openssl.org/support/donations.html

Re:Why Is SQLite Coded in C? (2017) by jt2190 on Wednesday March 14, 2018 @02:25PM (#16587081)
Can't it be both? We need it right now and we don't need to to work perfectly or last forever.

Really, we're talking about the same thing like they're two separate things: The software [1] (in this case, SQLite) and the application (whatever tables, queries, etc. you need to solve your problem) are used together. So we build the poorly tested, quick and dirty application on top of the well tested, solid software.

[1] Yes, I realize that "software" is a terribly generic term to use to mean "well designed and tested software" and that "application" is also a terribly generic term to use to mean "hastily designed and untested software". Feel free to mentally substitute your own terms if you have better ones.

Re:Why Is SQLite Coded in C? (2017) by simias on Wednesday March 14, 2018 @02:55PM (#16587305)
I wish that were true. I've worked on products that are very much not "disposable" and I've seen some terrible code and very poor testing infrastructure. It's especially bad in shops that were not primarily writing software and had to integrate software solutions to remain competitive. Execs don't understand it, don't care for it, don't invest enough resources in it. It's often delegated to some 3rd party and integrated like a black box in their solution.
Re:Why Is SQLite Coded in C? (2017) by msla on Wednesday March 14, 2018 @04:36PM (#16588070)
First: Apps can definitely be mission-critical. If you're lost somewhere dangerous, your GPS and mapping app can be as mission-critical as it gets. Your app which makes a phone call (and, yes, I'm calling the be-a-phone functionality of a cell phone an app here) can be mission-critical.

Is that software held to the standards of mission-critical software? Probably not.

Second: There's a lot of space between the software which is recognized as being mission-critical and software which is just Bioware's latest patch target, and that software includes things like web browsers and the web server software which hosts your company's website. Given how essential a web presence is to, you know, being able to make money, web server software is hardly disposable, but it is not held to the rigorous standards of mission-critical software.

Re:Why Is SQLite Coded in C? (2017) by khedoros1 on Wednesday March 14, 2018 @05:02PM (#16588268)
I think you're using the words differently than the post you're replying to. As defined in that post:

"apps": entertainment or disposable

"software": serious, mission critical

Aside from the difference in terminology, it sounds like your opinions go in the same general direction.

Re:Why Is SQLite Coded in C? (2017) by zerr on Wednesday March 14, 2018 @01:09PM (#16586328)
Regarding the viability, another thing to consider is that C gives you an ubiquitous compatibility.
Re:Why Is SQLite Coded in C? (2017) by kderbe on Wednesday March 14, 2018 @06:02PM (#16588719)
The Opus codec has an impressive amount of testing behind it as well:

https://www.ietf.org/proceedings/82/slides/codec-4.pdf

Re:Why Is SQLite Coded in C? (2017) by IloveHN84 on Wednesday March 14, 2018 @01:09PM (#16586325)
In Germany there are strict regulations if you're writing secure software, especially under the lens of BSI and of the Bundesdruckerei. Softwares which deal with eID are verified and certified with strict rules
Re:Why Is SQLite Coded in C? (2017) by signa11 on Thursday March 15, 2018 @03:09AM (#16590950)
> In Germany there are strict regulations if you're writing secure software, especially under the lens of BSI and of the Bundesdruckerei. Softwares which deal with eID are verified and certified with strict rules

just curious, does this extend to dependent libraries as well ?

Re:Why Is SQLite Coded in C? (2017) by epse on Thursday March 15, 2018 @03:24PM (#16595801)
Yup
Re:Why Is SQLite Coded in C? (2017) by z3t4 on Thursday March 15, 2018 @05:31AM (#16591397)
Most/All these tests are done by machine. Debugging (in production) (while your service is down) costs much more then writing a bunch of tests. The more states your program can be in the more rigorous tests are needed.
Re:Why Is SQLite Coded in C? (2017) by nialv7 on Thursday March 15, 2018 @06:01AM (#16591507)
SQLite went through thorough testing, not verification.

These are two different things.

Re:Why Is SQLite Coded in C? (2017) by adwn on Thursday March 15, 2018 @07:22AM (#16591820)
> SQLite went through thorough testing, not verification. These are two different things.

I think you're confusing the terms "formal verification" and "verification". Testing is a subset of verification, but not of formal verification.

Re:Why Is SQLite Coded in C? (2017) by crb002 on Wednesday March 14, 2018 @05:36PM (#16588520)
SQLite is litteraly used by the military in their Android phones.
Re:Why Is SQLite Coded in C? (2017) by sli on Thursday March 15, 2018 @04:46PM (#16596404)
It's literally used by every Android phone, military or not. It can be used in iOS apps, too.
Re:Why Is SQLite Coded in C? (2017) by phamilton on Thursday March 15, 2018 @01:55AM (#16590695)
> OOM tests are done in a loop. On the first iteration of the loop, the instrumented malloc is rigged to fail on the first allocation. Then some SQLite operation is carried out and checks are done to make sure SQLite handled the OOM error correctly. Then the time-to-failure counter on the instrumented malloc is increased by one and the test is repeated. The loop continues until the entire operation runs to completion without ever encountering a simulated OOM failure. Tests like this are run twice, once with the instrumented malloc set to fail only once, and again with the instrumented malloc set to fail continuously after the first failure.

That's pretty awesome actually.

Re:Why Is SQLite Coded in C? (2017) by bsenftner on Wednesday March 14, 2018 @02:02PM (#16586871)
I disagree. Another comment here mentions "military grade verification" (?!) is required to write such high quality C applications. No, not at all, unless you count knowing what you're engineering as Military Grade Awareness. You seem to be saying you prefer the code-slinging style of "see if it works, it seems to work... release it". I've been including SQLite in various applications for 10 years, as well as have been coding, primarily in C, for 35 years. If you are not testing your work to a degree of statistical awareness of it's behavior, you're an irresponsible cowboy, hardly a true professional, and probably a liability to you and your team.
Re:Why Is SQLite Coded in C? (2017) by dbaupp on Wednesday March 14, 2018 @05:22PM (#16588412)
This is almost a "no true scotsman": in practice, a lot of C projects and programmers (even ones that, by most other metrics, would be regarded as professional programmers) do not have the resources to test as extensively as SQLite.
Re:Why Is SQLite Coded in C? (2017) by blub on Thursday March 15, 2018 @03:58AM (#16591089)
It's more than that, it's a manipulative comment, designed to put others on the defensive about their own skills and muddle the issue.

Any real-world project will be developed unter specific time constraints and have a certain budget. There will be a mix of developers and other roles in the team, with varying skills. There will be politics involved and the project will probably be in use for decades, ensuring that all of the above will significantly change during its lifetime.

Under such conditions, C is an abject failure at supporting robust, quality code, because it neither benefits from a culture of safety (like Ada or even Rust) nor does it have any enforceable safety switches or indeed safety-by-default.

Anything that can be screwed up, will be screwed up over the years by someone, some configuration option, procedure or project management decision. Java is on average significantly safer than C or C++, because no matter what happens, the language won't allow certain errors to happen.

C can be assumed to be a hopeless case, but a purely theoretical way of avoiding these kinds of issues is to have a sufficient supply of bsenftner clones which will supervise a project through its development and operation until it's retired from production (assuming bsenftner is as awesome as they say).

Re:Why Is SQLite Coded in C? (2017) by buserror on Thursday March 15, 2018 @07:52AM (#16591984)
I agree, I'm paid by the hour to deliver a set of features, and the client very, VERY rarely would pay for me to start 'diverging' and writing test cases for something they see as superfluous. A bit of field tests (ie, users as testers) and if it works, it ships.

I don't make the rules. The scary bit is, often, it works just fine; in many cases, it's cheaper to reboot/relaunch for a 1/100000 crashing bug than paying me to find it and fix it!

Re:Why Is SQLite Coded in C? (2017) by Yoric on Friday March 16, 2018 @04:43AM (#16599382)
That's one of the reasons I'm pretty happy to work in a place where my manager will generally agree if I tell them that I'm planning to spend the next 3 months improving the test suite or harness or adding one layer of safety to eliminate a class of bugs or adding a new static analysis.

Of course, this is also a place where we practice static analysis, continuous integration, code reviews and we're now progressively migrating code to Rust.

Re:Why Is SQLite Coded in C? (2017) by TheDong on Wednesday March 14, 2018 @02:13PM (#16586956)
The evidence is on the side of the parent poster.

Incredibly experienced programmers write C without those tools, and with practically no exceptions memory issues, crashes, and vulnerabilities surface if the code is large enough and the project used enough.

An easy example of this is the Linux kernel. They historically had relatively few verification tools and have one of the largest C codebases out there. There's a new vulnerability related to memory safety every two or three weeks. There's a bug fixed due to C memory management at least daily.

None of those bugs would have happened in Rust. Most of them couldn't have happened in well written C++ (whereas this well-written C is chock full of them).

Note as well that the kernel now gets some of the most exhaustive verification of any project (such as from google's syzkaller, etc), and it still has tons of C memory issues.

Re:Why Is SQLite Coded in C? (2017) by bsenftner on Wednesday March 14, 2018 @02:48PM (#16587252)
"Incredibly experienced programmers" ? The language is simple and well defined to the degree one can map out exactly what happens on paper, if need be. Everyone is so brainwashed to think C is some low level assembly like language that is "hard". No, not at all. It simply provides no training wheels or safety harness - meaning one needs to know what they are doing, not coding in a "type and see what it does" style.
Re:Why Is SQLite Coded in C? (2017) by kccqzy on Wednesday March 14, 2018 @04:57PM (#16588227)
> The language is simple and well defined to the degree one can map out exactly what happens on paper, if need be.

Without a copy of the language standard, I still can't remember all the intricate details about just arithmetic and comparison operators. Take the simple bitshift operators. What happens when the second operand is negative or larger than sizeof(left)*CHAR_BITS? What if it's equal? And the >> and << operators are not even symmetric in their definitions: left-shifting a negative value is undefined but right-shifting a negative value is implementation-defined! And even for simpler operators like + or >, can you immediately tell me all the integer promotion rules and usual arithmetic conversion rules? What happens when you add two integers with different signedness and width?

I can't and I doubt most programmers can. Try implementing a special C interpreter where every undefined and implementation-defined behavior is configurable and you will see how complicated things are.

Re:Why Is SQLite Coded in C? (2017) by jstimpfle on Wednesday March 14, 2018 @09:17PM (#16589800)
> What happens when the second operand is negative or larger than sizeof(left) * CHAR_BITS? What if it's equal? And the >> and << operators are not even symmetric in their definitions: left-shifting a negative value is undefined but right-shifting a negative value is implementation-defined!

As a lover of C, these questions are totally irrelevant to me. What I've taken away is don't do things that do not have intuitively clear semantics. Use bitwise and shift operators only on unsigned numbers. Simple as that. And really I haven't found a need to do anything else. I think many of these complex rules are historical accidents or come from supporting a peculiar architecture or kind of hardware that's no longer relevant. In any case, remembering all these pesky rules is not C. C is simple. Remember how to stay away from the dubious operations and you're fine.

Re:Why Is SQLite Coded in C? (2017) by aidenn0 on Thursday March 15, 2018 @02:36AM (#16590844)

    uint32_t foo(uint8_t ubyte) {
        return ubyte << 24;
    }
Look ma, undefined behavior due to signed integer overflow (on 32 bit targets anyways), despite only unsigned types being declared.

And what about the aliasing rules:

    char *start, *end;
    //This is a function that sets start/end to the start and end of an address range.  It takes uintptr_t * arguments
    GetAddressRange((uintptr_t *)&start, (uintptr_t *)&end);
    *start=3; //Undefined behavior because we have now accessed start as both a uintptr_t and a char *.
Re:Why Is SQLite Coded in C? (2017) by jstimpfle on Thursday March 15, 2018 @03:58AM (#16591086)
The first is nice, but I think you should make sure that ubyte really has that many bits for it to make sense, no? And doesn't your compiler emit a warning if it takes advantage of that undefined behaviour? (e.g. using the upper part of the register where that byte is stored).

The second, why do you cast as uintptr_t? It makes no sense to me at all. Yep, it might be a little bit advanced, but it's well known that you should only have correctly typed pointers, or void pointers, or char pointers, to any object. It's not a totally obscure thing, just as most people understand the need for "restrict". I'd say the code looks bad to me at first sight, and even a beginner is unlikely to write it because it's a complicated construction.

You have your point, but anyway the pointer-type rule makes sense and I don't know a better version of the rule that could prevent many unnecessary reloads.

Re:Why Is SQLite Coded in C? (2017) by aidenn0 on Thursday March 15, 2018 @01:33PM (#16594853)
With the first, John Regehr found many, many examples of it in real world code, and in some cases the bug he filed was closed without fixing it because "no compiler currently will do the wrong thing with it." I'm not aware of any compiler that emits a warning for this with default compilation flags.

The second is based off of code where an operating system call would get the mapped ranges of a shared memory region. For whatever reason, it took a MemoryAddress which was essentially a pre-c99 uintptr_t defined by the system headers (an unsigned value large enough to hold an address). The casts were there because the compiler warned about incompatible pointer types.

I was never able to convince the engineer who wrote the code (~20 years of C experience) that this code was wrong (it worked fine until intermodule inlining was enabled). Instead we just enabled the compiler option to disable optimizations based off of aliasing rules.

You are both greatly overestimating the degree to which programmers understand C, and overestimating the degree to which programmers who do understand C do not make mistakes. I've had lots of people say that the code in the second example "looks bad to me" but the commit still made it through code review and was being run for 5 years before optimization flag changes caused bugs to appear.

Re:Why Is SQLite Coded in C? (2017) by jstimpfle on Thursday March 15, 2018 @05:32PM (#16596692)
> "no compiler currently will do the wrong thing with it."

Well then, that's nice no? I don't like to play language lawyer. If there are machines were it can lead to errors, it might be bad machine design. The compiler or the user should work together to catch the error / specify more precisely what is the intent. If we can assume that (ubyte << n) == 0 for any n >= 8, I'm very fine with that, too.

I don't think compilers should exploit every undefined behaviour in the C standard. Some of those might be there only to support rare, quirky architectures.

> For whatever reason, it took a MemoryAddress which was essentially a pre-c99 uintptr_t defined by the system headers

That's inconvenient that the API forces such a strange type to the user. But I think the logical usage is to declare "start" and "end" as uintptr_t then. In this case there should be no problem, or do I miss something?

> You are both greatly overestimating the degree to which programmers understand C, and overestimating the degree to which programmers who do understand C do not make mistakes.

All I can say is I've never had this kind of problem really, so far. The kinds of problems I get by using safe toys on the other hand (e.g. array access only possible through proxy containers) are incredibly more painful, because these approaches are extremely bad for modularity and elegance. You have to specify the container, and also its type, or at least implement all kinds of boilerplate interfaces. This is incredibly restricting.

Everybody makes mistakes and while some memory safety problems definitely happen regularly even to very experienced coders, and are harder to detect than e.g. an exception, they are also the minority of the problems I encounter, even when counting the occasional buffer overrun or similar. Even in terms of data security, I figure more exploits are high-level (i.e. logic errors not catched in a high-level language - SQL injection or other auth bypass) than clever low-level ones. And not every type of program is extremely security-sensitive.

Re:Why Is SQLite Coded in C? (2017) by aidenn0 on Thursday March 15, 2018 @09:46PM (#16597992)
>> "no compiler currently will do the wrong thing with it."

> Well then, that's nice no? I don't like to play language lawyer. If there are machines were it can lead to errors, it might be bad machine design. The compiler or the user should work together to catch the error / specify more precisely what is the intent. If we can assume that (ubyte << n) == 0 for any n >= 8, I'm very fine with that, too.

> I don't think compilers should exploit every undefined behaviour in the C standard. Some of those might be there only to support rare, quirky architectures.

In this case, it would be legal for a compiler to assume that ubyte is less than 128. It's not unreasonable to assume that at some point in the future a compiler writer will discover a way to get a 0.1% improvement on whatever the current artificial benchmark of the day is and implement an optimization for it. The landscape of C libraries is littered with undefined code that used to work everywhere and now doesn't for just such a reason.

>> For whatever reason, it took a MemoryAddress which was essentially a pre-c99 uintptr_t defined by the system headers

> That's inconvenient that the API forces such a strange type to the user. But I think the logical usage is to declare "start" and "end" as uintptr_t then. In this case there should be no problem, or do I miss something?

Yes, the correct way is to declare them as uintptr_t and then assign them to a pointer of whatever type you need. It's not uncommon for systems software to treat addresses as integers in places, because they actually do represent specific addresses. I'd have to re-read the specification, but I think that having it take a void instead of a uintptr_t * would have the exact same issue, so I don't think it's the odd API choice that causes this.

Re:Why Is SQLite Coded in C? (2017) by jstimpfle on Friday March 16, 2018 @06:31AM (#16599723)
I don't think there should be a problem. I think you can cast to void * and back as much as you like, but you aren't supposed to ever access the object as something else than char or its original type.
Re:Why Is SQLite Coded in C? (2017) by Yoric on Friday March 16, 2018 @05:01AM (#16599435)
> I don't think compilers should exploit every undefined behaviour in the C standard. Some of those might be there only to support rare, quirky architectures.

Well, that is one way of looking at it. My personal experience is that if there is an undefined behavior in the C standard, it will be exploited, eventually. I have seen this break millions-of-lines applications during compiler upgrades and/or flag-twiddling. As you can imagine, debugging that problem was a nightmare.

[...]

> Everybody makes mistakes and while some memory safety problems definitely happen regularly even to very experienced coders, and are harder to detect than e.g. an exception, they are also the minority of the problems I encounter, even when counting the occasional buffer overrun or similar. Even in terms of data security, I figure more exploits are high-level (i.e. logic errors not catched in a high-level language - SQL injection or other auth bypass) than clever low-level ones. And not every type of program is extremely security-sensitive.

I believe that you are right in terms of number of exploits, but for the wrong reasons.

I can't find the statistics on this, but from the top of my head, ~20 years ago, 80% of the security advisories were buffer overflows/underflows. At the time, just about everything was written in C/C++.

These days, we see lots of high-level exploits, but I would tend to assume that the reason is that 1/ the web makes it very easy to carry out attacks; 2/ C and C++ have a very small attack perimeter on the web, even if you include Apache/nginx/... as part of the web.

Also, yes, web applications, especially in dynamically typed languages also would require military-grade testing :)

Re:Why Is SQLite Coded in C? (2017) by wahern on Thursday March 15, 2018 @07:19PM (#16597354)
The first is only undefined on 16 bit targets as ubyte is first promoted to int, and int is always at least 16 bits but on typical general purpose machines 32 bits. And in any event modern C compilers will emit a diagnostic when constant shifts are undefined--just not in this case because it's not actually wrong.

The latter problem[1] is applicable to other languages, including Rust, when they permit such type punning. C supports type punning because occasionally it's useful and necessary. The above invokes UB on Rust, too. Type punning has such a horrible code smell that you don't need unsafe{} as a gateway. Maybe for very inexperienced programmers, but they shouldn't be writing C code in situations where type punning suggests itself anymore than they should be writing assembly or unsafe Rust code.

C has many pitfalls, but I don't think I'm being overly pedantic here. There's no question C gives you a significant amount of rope to hang yourself (sometimes affirmatively but usually by turning its head when you steal some), but all languages give you slack to escape the limitations of how they model the environment--the points of contention are how much slack and at what cost. Arguing that requires more precision.

For example, even if we can agree that automatic arithmetic conversions are on balance a bad idea, it's still the fact that there's some benefit to that behavior, such as making your first example well-defined. That's not coincidental.

[1] It's actually only a problem if that routine actually stores the value through a uintptr_t pointer. If it casts the parameter to pointer-to-pointer-to-char before the store it's fine. You can cast a pointer to whatever you want, as many times as you want, and never will the casting, alone, change the semantics of the code. It's only actual load or store expressions that matter, and specifically the immediate pointer type they occur through.

Where you typically find code like this you do the correct thing--the abuse of function parameter types in this particular manner is usually because of const-ness headaches and the lack of function overloading (though now there's _Generic), and in those cases you're already paying attention to type punning pitfalls because you're already at a point where you're trying to skirt around relatively strict, inconvenient typing. If you're not then, again, you're not going to be doing the right thing when writing unsafe Rust code--and there are many more cases where Rust's strict typing is inconvenient, so arguably there's _greater_ risk with a language like Rust when the programmer is lazy or tired and resorts to subverting the type system.

Moreover, this isn't even a pointer aliasing problem. Pointer aliasing problems occur when the _order_ of loads or stores matters, but because of type punning the compiler can neither determine nor assume that access through variables of _different_ type point to the same object and thus it mustn't reorder the sequence. Not only is your example not a case of a single object accessed through multiple types across dependent loads and stores, it's not even a case of accessing through the same type. Unless you use the restrict qualifier, the compiler always assumes that two variables of the same pointer type alias the same object. Whether it's the _wrong_ type is a different, less consequential problem related to the potential for trap representations or alignment violations. But if the hardware doesn't care you'll get expected behavior; it's not the type of pitfall that threatens nasal daemons.

Re:Why Is SQLite Coded in C? (2017) by aidenn0 on Thursday March 15, 2018 @09:38PM (#16597962)
> The first is only undefined on 16 bit targets as ubyte is first promoted to int, and int is always at least 16 bits but on typical general purpose machines 32 bits. And in any event modern C compilers will emit a diagnostic when constant shifts are undefined--just not in this case because it's not actually wrong.

If ubyte is greater than or equal to 128, then converting it to a signed 32-bit integer (as on a 32 bit machine) and then shifting it left by 24 causes signed integer overflow. This is undefined behavior. Therefore the compiler is allowed to make optimizations that assume ubyte is less than 128.

Re:Why Is SQLite Coded in C? (2017) by jstimpfle on Friday March 16, 2018 @04:57AM (#16599422)
Why is the ubyte promoted to int? I'd always assumed it would stay the same size.
Re:Why Is SQLite Coded in C? (2017) by kccqzy on Friday March 16, 2018 @08:25PM (#16604950)
Look up integer promotion rules. Basically almost all arithmetic operators promote their operands to int/unsigned int before doing anything.

And you are the person who replied to my earlier post saying "don't do things that do not have intuitively clear semantics." Do integer promotion rules count as intuitively clear semantics? Most C programmers never learned them and therefore the semantics is confusing. For the few C programmers who learned them, the semantics is clearer when they can remember the rules, and confusing otherwise.

Now I hope I've convinced you that there are a lot of such subtle semantics issues in C, and hardly anything is intuitively clear, unless you've been a language lawyer or programmed in C for long enough.

Re:Why Is SQLite Coded in C? (2017) by jstimpfle on Saturday March 17, 2018 @11:27AM (#16607359)
Point taken. I agree that the weakly typed nature of C (integer promotions / implicit casts) can be problematic. Would be interesting to see if there are programs that would be painful to write with a stricter model.

It seems I've never really done "overshifting", otherwise I would have easily noticed that the shifted value is promoted first. If you don't overshift there's no way to trigger the undefined behaviour, even when you shift multiple times - since by assigning to the smaller type the result gets cut down again, effectively leading to the behaviour I'd assumed. I would hardly call this a gotcha.

Where it might be confusing is in a situation like this:

    char x = 42;
    printf("%d\n", x << 4);
But then again I'm undecided if the behaviour is that bad. It might be even useful.
Re:Why Is SQLite Coded in C? (2017) by bunderbunder on Wednesday March 14, 2018 @03:04PM (#16587372)
"type and see what it does" is a strawman. Some people absolutely do program this way, I don't deny that, but there's a huge gulf between that and the levels of verification it takes to ensure that a large program really does behave as intended. Typos, minor oversights, unforeseen consequences of refactoring. . . the number of things you need to guard against is immense, and nobody can be operating at 100% 100% of the time.
Re:Why Is SQLite Coded in C? (2017) by liuliu on Wednesday March 14, 2018 @04:08PM (#16587847)
And very few people can know 100% 100% times. We build software on top of abstractions. Abstraction leaks, abstraction breaks and abstraction isolates you from "know what you are doing".

If you build software in C, you will build abstractions in C, and debugging / analysis tools help to understand these abstractions.

Re:Why Is SQLite Coded in C? (2017) by TheDong on Wednesday March 14, 2018 @02:51PM (#16587271)
> It simply provides no training wheels or safety harness - meaning one needs to know what they are doing

Meaning that if you are human you will make mistakes.

My point is that people who do know what they're doing still make mistakes. Clearly the tool does not match the reality of human cognition.

Re:Why Is SQLite Coded in C? (2017) by geezerjay on Wednesday March 14, 2018 @03:44PM (#16587662)
> Meaning that if you are human you will make mistakes.

You can make mistakes in any language, and they will bite you in the backside any way.

Just because some people prefer to live in padded rooms that doesn't mean they can't or won't get hurt if they decide to pull stunts. Padded rooms just provide them with a false notion of safety that ends up making matters worse.

Re:Why Is SQLite Coded in C? (2017) by TheDong on Wednesday March 14, 2018 @04:11PM (#16587882)
> You can make mistakes in any language, and they will bite you in the backside any way.

This is a false equivalency.. It's akin to saying "you can hit your thumb putting in a nail with any tool, so you might as well use a rock not a hammer since they're both bad".

Yes, you can make mistakes in any language, but that's not a reason to ignore modern tooling and advances and continue.

Other languages allow us to build abstractions and solve mistakes in ways which are just impossible with C... and without those abstractions, it's just needlessly difficult to keep all the state in your head and write correct code.

An easy example of this is locking and ownership. In C, mutexes are managed manually and what they hold is by convention. It's easy to write races or accidentally deadlock (again as evidenced by such a bug in the kernel existing every few weeks).

In languages with RAII, python's "with", etc, you can't forget to unlock the lock. It's one less thing to think about.

In languages like rust, it's possible to model in the type system that a given resource can only be accessed while a mutex is locked. Again, one less way to make a mistake.

C has no ability to provide or build abstractions that are this robust.

Using C is, more often than not, like using a rock to hammer in a nail.

> Just because some people prefer to live in padded rooms

With C, people are living in a room where the floor is lava and nails coat most surfaces.

I'll take my room that's carpeted, and if I need to pull a stunt and rip up the carpet, sure, I can do that, but at least I can walk normally most of the time.

Re:Why Is SQLite Coded in C? (2017) by amag on Wednesday March 14, 2018 @05:02PM (#16588264)
> It's one less thing to think about.

I've been a professional C++ programmer for almost two decades (and a C++ amateur for almost a decade before that). I've written large amounts of fairly advanced C++ using the latest standards.

My current job however, is all plain C.

One of the interesting (and, for a C++ fan like me, disturbing) things I've found is that the cognitive load is much lower when writing plain well-structured C.

Sure, you need to remember to release that lock and free that memory but this you can do in a very structured way. What you win over C++ is that you don't need to view each line of code with suspicion ("What happens if this line throws an exception?", "I wonder what this line will cost in terms of performance?", "Could this operation cause a cascading destruction of objects I'm going to access further down?").

I love RAII, yet I've debugged enough crashes where "seemingly innocuous operation destructs some local object that has an owning reference to an object that shouldn't be destructed just yet and BAM!", that I'm beginning to doubt its usefulness outside of an exception-generating language (in C++ it's essential for proper exception-handling).

Re:Why Is SQLite Coded in C? (2017) by 52-6F-62 on Wednesday March 14, 2018 @07:53PM (#16589428)
Even from a C amateur point of view I feel the same way in my learning of the language. I can’t speak to multithreading or very large applications yet— but the view from the ground looking up is that C is relatively straightforward. The small size of the language is something of a relief.
Re:Why Is SQLite Coded in C? (2017) by blub on Thursday March 15, 2018 @04:05AM (#16591113)
It's not very surprising for me, because C is a simpler language and it's easy to paint yourself into a corner with C++.

The critical question is: what does the error rate look like for code of similar complexity? It's very possible that C programmers will try to keep things simple, because the language doesn't support them and they have to be extra careful. The flip-side is that they probably can't develop projects as complex as C++ would enable them to.

Re:Why Is SQLite Coded in C? (2017) by falcolas on Wednesday March 14, 2018 @06:49PM (#16589064)
> Sure, you need to remember to release that lock and free that memory

It's always bothered me how complex of an operation people seem to think this is.

    errno = pthread_mutex_lock(&m);
    if (errno == 0) {
       do_something();
       pthread_mutex_unlock(&m);
    }
Short of a segfault or 'do_something' doing something really, unusually stupid, you can't avoid freeing the mutex.
Re:Why Is SQLite Coded in C? (2017) by blub on Thursday March 15, 2018 @04:08AM (#16591124)
Yeah, most projects don't consist of a single function locking and unlocking a mutex. :) Try doing the same in five 200 LOC functions with multiple returns when three different threads are sharing the data, for 10 years, with a yearly personnel turnover of 20%.
Re:Why Is SQLite Coded in C? (2017) by falcolas on Thursday March 15, 2018 @09:31AM (#16592647)
Been there done that, fought similar problems. Deadlocks abound.

Only difference? We were in Python.

Re:Why Is SQLite Coded in C? (2017) by aidenn0 on Thursday March 15, 2018 @02:38AM (#16590857)
Something really unusually stupid like returning from the function (assuming do_something() is a standin for arbitrary code, not specifically a function call)?

This is not even remotely the worst thing about mutexes though, so it wouldn't be why I would suggest avoiding them.

Re:Why Is SQLite Coded in C? (2017) by falcolas on Thursday March 15, 2018 @09:39AM (#16592705)
Honestly, to help avoid mistakes, I would keep it as a function call. Sure, it adds to the stack depth, but it also ensures a separate return doesn't cause the lock to be lost.

There's also the goto pattern, but anytime you separate a lock from an unlock by more than a screen's worth of text, they're forgotten.

Re:Why Is SQLite Coded in C? (2017) by aidenn0 on Thursday March 15, 2018 @01:40PM (#16594919)
And inline functions don't even add stack depth. It's still something that happens manually though. Every item that needs to be done manually and doesn't cause obvious failures when not done adds to development costs.
Re:Why Is SQLite Coded in C? (2017) by nwmcsween on Friday March 16, 2018 @03:53AM (#16599240)
And this is my unpopular complaint of programming in Rust, there is so much complexity not to do with the type system that reasoning becomes a pain.
Re:Why Is SQLite Coded in C? (2017) by falcolas on Wednesday March 14, 2018 @06:39PM (#16588985)
I'm glad you mentioned Python. Python, with its developers who accept raw pickle objects from the wild and are surprised when arbitrary code can be executed. Ruby's (and Python's) YAML libraries which execute arbitrary code. Javascript (and Ruby, and Python) developers pulling in untrusted and/or poorly tested libraries just to save a few lines of code. Rust with its `unsafe` blocks.

Seems like that padded floor has some rusted nails hiding right behind the pretty fabric.

RAII is not something limited to Rust, or C++, or any other language. The abstraction underpinning RAII can be done and has been done in C; you can see it done repeatedly in the code for collectd.

Its up to the developers to make their programs safe and reliable. No language to date will do that for them.

Re:Why Is SQLite Coded in C? (2017) by willtim on Thursday March 15, 2018 @04:36AM (#16591198)
> Its up to the developers to make their programs safe and reliable. No language to date will do that for them.

But languages do make a huge contribution. For example, Rust, Ada and Modula-3 are all much safer by defaults alone compared to C. Most Rust code sits outside unsafe blocks, so the existence of this feature does not prove there is no point to Rust.

Re:Why Is SQLite Coded in C? (2017) by falcolas on Thursday March 15, 2018 @09:28AM (#16592617)
> does not prove there is no point to Rust.

I didn't say anything along those lines. I said that it's up to developers to make their programs safe.

Defaults matter, no doubt. But they are not a silver bullet; greater base safety can even cause people to become lax when thinking about safety, resulting in even bigger problems. Why do Python developers accept and parse untrusted pickle objects? Because Python is safe, and they don't have to think about what's going on under the hood.

It's indirectly related to computer programming, but a study was done in Europe which showed that crashes in AWD vechicles were, on average, much more severe than 2WD vehicles. Why? Because of the added stability of AWD, people drove faster in adverse conditions.

Re:Why Is SQLite Coded in C? (2017) by gowld on Thursday March 15, 2018 @06:50AM (#16591706)
C doesn't have destructors, so how do you release resources acquired with RAII when the acquiring object goes out of scope?
Re:Why Is SQLite Coded in C? (2017) by steveklabnik on Thursday March 15, 2018 @07:48AM (#16591951)
C programmers, in my experience, will use a "goto cleanup" pattern to emulate RAII in this case https://softwareengineering.stackexchange.com/a/154980
Re:Why Is SQLite Coded in C? (2017) by gowld on Thursday March 15, 2018 @06:46AM (#16591691)
I'm glad that you are a video game programmer and you don't work on software where correctness matters.
Re:Why Is SQLite Coded in C? (2017) by mbrodersen on Thursday March 15, 2018 @11:04PM (#16598268)
You clearly don't understand the world of video game programmers. I worked on a game (Banjo Kazooie) that ended up being turned into more than 6 million ROM cartridges and distributed worldwide through retail. The cost of producing the cartridges alone was millions of $. With no internet patching available in case of a bug. We took verification VERY seriously.
Re:Why Is SQLite Coded in C? (2017) by jmull on Wednesday March 14, 2018 @03:28PM (#16587568)
I'm calling BS here.

Look at the types tests listed in the executive summary... which of these can be obviated by language features?

I'll try to break it down:

* Out-of-memory tests: no, all languages run out of memory. The explicit nature of memory management in C might help here, since there's no mystery about exactly where the failure might occur.

* I/O error tests: no, IO failures are independent of language.

* Crash and power loss tests: no, this has nothing to do with language.

* Fuzz tests: yes, partially. Different languages can reduce the range of invalid input a program could encounter.

* Boundary value tests: yes, partially.

* Disabled optimization tests: no, the optimizations being referred to here is a feature of SQLLite, which would need to be tested, regardless of language.

* Regression tests: no, this is independent of language.

* Malformed database tests: partially, because some languages are better at validating input statically, which covers some of the cases of malformed databases.

* Extensive use of assert() and run-time checks: I say no. Yes, asserts are code you need to write, and a cognitive load. But navigating the built-in language constraints of more type- and value- validating languages are also a cognitive load. I believe asserts are often a lessor load since they can be in the problem space of the software being developed vs. the problem space of the language design. In C the molehill comes to the mountain. OK, Ok, on the other hand, in C no one forces you to write good asserts. But then, in no language does anyone force you to write code that actually does the job.

* Valingrad analysis: yes

* Undefined behavior checks: yes

So, largely no. Other languages solve some problems, yet have their own drawbacks.

You're drawing a sharp distinction between "C" and "C with analysis backing", yet there is no such distinction in the real world. We see in this project what we would see in every successful, long-running project (and do NOT see, 100%, in every project that failed in the long-run): controls in place to deal with the potential pitfalls. One advantage to C is that it's history can give you some nice guidelines to understand when you have pretty good coverage on those, from a language standpoint.

I mean, I'm not arguing that some modern languages have their advantages. But, they have disadvantages as well. And, their advantages -- restricted as they are to static analysis -- solve little problems, not the bigs ones.

Re:Why Is SQLite Coded in C? (2017) by jerf on Wednesday March 14, 2018 @03:35PM (#16587612)
I never claimed that language features can obviate all the things. I'm just saying that you can't use SQLite as proof that C is A-OK okey dokey it's OK to just keep programming in it forever, because it does not use C. If you're not putting in that much effort to your C codebase, then you're not getting those results.

Also, while I'm sure you don't intend it this way, simply listing the issues like that is a bit visually deceptive in that our hindbrains tend to assume all those issues are roughly equally weighted, because they're all roughly equally the same size. But the distribution of issues there is very non-linear. C doesn't just have a bit of an issue with undefined behavior; it is nearly (but not quite) uniquely damaged by it.

Hypothetically some type systems could partially cover some of the things you've labelled as "no", but I'll aggressively beat you to the punch that such things are very hypothetical, except I'll be saying it with sadness and through grinding teeth, because I find it frustrating how thoroughly our environments ignore some issues like that. But that's a rant for a century I don't expect to live to see.

Re:Why Is SQLite Coded in C? (2017) by jmull on Wednesday March 14, 2018 @05:29PM (#16588461)
> If you're not putting in that much effort to your C codebase, then you're not getting those results.

My point is, if you're not putting that much effort into your codebase -- whatever the language you're not getting those results. There is no language that makes developing and maintaining SQLLite easy or straightforward.

Re:Why Is SQLite Coded in C? (2017) by cgoughnour on Wednesday March 14, 2018 @04:55PM (#16588212)
>Hypothetically some type systems could partially cover some of the things you've labelled as "no", but I'll aggressively beat you to the punch that such things are very hypothetical, except I'll be saying it with sadness and through grinding teeth, because I find it frustrating how thoroughly our environments ignore some issues like that. But that's a rant for a century I don't expect to live to see.

I'd agree with you, except that just this morning I was reading a paper about the NARCISSUS framework that can automatically generate encoders and decoders that provably conform to a given specification, and can be extended by a user without rewriting or modifying the framework itself. The authors even patched a networking stack (in MirageOS) with the not-especially-optimized ML extracted from their generated code and showed a performance hit that could be considered acceptable for real-life use cases.

https://www.cs.purdue.edu/homes/bendy/Narcissus/

With advances like this in program synthesis and formal verification, plus real progress in machine learning, it feels like we're living in the start of the age that was _supposed_ to happen during the golden age of AI.

(Excuse the gushing hyperbole. My coffee must have been stronger than usual this morning.)

Re:Why Is SQLite Coded in C? (2017) by geezerjay on Wednesday March 14, 2018 @03:59PM (#16587773)
> I never claimed that language features can obviate all the things.

You did more than that: you've suggested that C was only usable if a pile of safety infrastructure by providing sqlite as your proof, and once that claim was debunked you kept insisting on your baseless assertion.

> I'm just saying that you can't use SQLite as proof that C is A-OK okey dokey

There is no need to prove that because it's quite obvious that C is fine. If you feel the need to prove otherwise then you need to put forward your own proof. Either you support your baseless assertions with rational and tangible claims or you're just venting an irrational dislike. Meanwhile the world runs on C and has been running for decades.

> it's OK to just keep programming in it forever, because it does not use C. If you're not putting in that much effort to your C codebase, then you're not getting those results.

You're somehow turning a blind eye to the fact that that "effort" is patently language-independent and has absolutely nothing to do with C. Either you somehow missed the whole point of the post or for some reason felt the need to keep repeating baseless claims that were already debunked.

I have no idea why you've developed an irrational hatred of C, but it clearly is a personal issue, not a technical one.

Re:Why Is SQLite Coded in C? (2017) by willtim on Thursday March 15, 2018 @04:29AM (#16591184)
> There is no need to prove that because it's quite obvious that C is fine.

No. It is quite obvious to anyone rational and without a vested interest that C is no longer fit for purpose in this modern age.

> I have no idea why you've developed an irrational hatred of C

Let me guess. He's sick of patching security holes, memory leaks and crashes?

Re:Why Is SQLite Coded in C? (2017) by aidenn0 on Wednesday March 14, 2018 @02:02PM (#16586870)
Wow.

Any one of the 3 test subsystems the describe is already ahead of well more than 99% of all software projects being developed. How is this funded?

Re:Why Is SQLite Coded in C? (2017) by kzrdude on Wednesday March 14, 2018 @05:35PM (#16588513)
This talk is really interesting too https://www.youtube.com/watch?v=Jib2AmRb_rk big industry projects (like the airline mentioned) probably contribute
Re:Why Is SQLite Coded in C? (2017) by LusoTycoon on Wednesday March 14, 2018 @02:45PM (#16587236)
Re:Why Is SQLite Coded in C? (2017) by distances on Thursday March 15, 2018 @07:47AM (#16591947)
> Consortium members can call any developer at any time, day or night, and expect to get their full and immediate attention

I wonder how this works. For sure even the most dedicated developers will every now and then be on a holiday / concert / drunk.

Re:Why Is SQLite Coded in C? (2017) by ksec on Wednesday March 14, 2018 @03:13PM (#16587459)
Wow, I never knew SQLite was that well tested!

I was recently looking at bedrockdb, and other DB built on top of it.

Anyone knew what happen to UnQLite ? By the same author.