But then the person RUNNING the program will only see this:
Abort trap: 6
And that's all the info you'll get from their bug report.So please ignore this directive and print a descriptive message always, complete with file and line, and the values that led to the impossible situation. Then you can get helpful bug reports like:
BUG: flush.c:51: buff_offset (65535) must not be greater than 20!
Abort trap: 6There is another aspect, C and C++ are not memory safe languages so the bug may not be particular logical (i.e. some kind of memory corruption). In these cases I actually prefer something to the like of __builtin_trap instead of abort. Calling any code after an invalid invariant has been detected clobbers registers and may make it impossible to investigate the state at the time of the "crash". Some features of modern optimizing compilers make this even worse, such as abort being marked as "noreturn".
Back in the early days, this sentence was more like "When you want to use a language that gets compiled and runs at high speed, the best language to use is C.".
So we switched from a path where all major desktop environments (OS/2, Mac, Windows, UNIX) were adopting C++ to a surge in C programming, as FOSS adoption started to gain steam.
So here we are now, about 30 years later, trying to fix the security inconveniences caused by this manifesto.
So you say FLOSS is responsible that the late 90s/early 2000s C++ hype slowly died off?
> trying to fix the security inconveniences caused by this manifesto.
And you believe those projects chose C, solely because some random GNU document suggested they do?
If that document didn't exist they would have chosen what? C++98? Java? Ada?
Had GNU/Linux not taken off, in the alternative universe from Windows, BeOS, Mac OS, OS/2, commercial UNIX (remember Motif++ and CORBA?) would kept writing the software in C++, instead of caring about creating FOSS stuff in C.
GNOME vs KDE is a good example of that schism and language wars.
Windows has more exploits than Linux. But you know all that, so I wonder why you keep making these statements, which are then upvoted by the "memory-safe" crowd.
any source for that ? I find segfaults utterly rare in C++ >= 11
That sounds backwards to me. It wasn't a "manifesto" that caused that "surge", it was the actual software being written.
Free software beat the world. Free (system) software is overwhelmingly written in C. At least part of an argument like this needs to nod to the fact that free software written in C beat the world because... C was a better choice? Certainly it was in the 90's.
If it's too slow, then you probably have an issue with which algorithm/data structure you chose and would have had the same issue in another language.
The biggest issue I have with C today is that you can't trust that your compiler actually generates code that is 1:1 with what you wrote. I'm not talking about UB here, your compiler can actually remove code/checks even though you don't invoke UB.
Then we have UB, I think UB should be removed from the spec completely. There probably was a point in time when leaving stuff as UB was the best option, but today speed is seldom the problem, correctness is.
I no longer work as a C programmer, but I still love the language and I really enjoy writing C code, but I really would like to get rid of UB and have a compiler I can trust to generate code even when I turn on optimizations, and having optimizations off is not an option either, since it can generate broken code as well, so...
Especially when you add this line, you're telling me that what you want is not to program in C but to program in a language which differs from C not in syntax but in semantics, and in otherwise vaguely undefined terms [1] there. And you're mad that compilers implement C instead of your not-C.
I find claims that you can safely write secure code in C hard to believe when you marry them with complaints about compilers not implementing not-C correctly. Especially given that virtually every new sanitizer and static analysis tool to find issues in C code manages to turn up issues in code that is rigorously tested to make sure it passes every known prior tool (e.g., SQLite).
[1] From prior experience, this tends to be best distilled as "the compiler must read the programmer's mind."
I also don’t believe that a single person on the planet can write a secure c program of meaningful complexity. Static analysis tooling has demonstrated that it isn’t up to the task of saving developers from themselves.
Are there good examples of what you mean by this? From my own C++ experience, when dealing with c libraries and std::string types, I'll sometimes use the copying api's[0] when passing around std::string::c_str() because I find it easier than worrying about invalidating the returned reference if the string is destructed or modified.
[0]: e.g. https://curl.se/libcurl/c/CURLOPT_COPYPOSTFIELDS.html
- proper string and vector types (most compilers allow to enable bounds checking anyway)
- stronger rules for type conversions
- reference types for parameters
- better tooling for immutable data structures
- memory allocation primitives instead of getting sizeof wrong to malloc()
- collection library instead of reinventing the wheel in each project
- RAII
- smart pointers
- templates instead of error prone macros
- namespacing (usefull in large scale projects with prefix tricks)
>>> Please don’t use “win” as an abbreviation for Microsoft Windows in GNU software or documentation. In hacker terminology, calling something a “win” is a form of praise. You’re free to praise Microsoft Windows on your own if you want, but please don’t do so in GNU packages. Please write “Windows” in full, or abbreviate it to “w.”
But they have removed some other guidance:
>>> Instead of abbreviating “Windows” to “un”, you can write it in full or abbreviate it to “woe” or “w”.
I think C is a beast for standard in general due to it's rogue history. Now when a language like Rust or Go is created, standards are released with the code via formatting tools that enforce consistency (which I'm all for).
The amount of time I've seen C code with inconsistencies within a single file (naming, spacing, you name it) from fellow students back when I was in college was insane.
Enforced code style standards are great, even if I don't agree with them. Go's public vs private distinction is a good example. I really am not a huge fan of the pascal vs camel case to denote private and public (it's grown on me a bit, but still not a fan), but I know their code is going to be reasonable (in looks) because Go is very picky about how the code looks.
Would be interested to know examples for this.
Unix utilities in the old days weren't all that great. One example I've posted about here before is how mv would refuse to move files across filesystem boundaries (because it's not a 'move', it's a 'copy and delete', so you had to use cp and rm instead).
- The doc on Linux kernel coding style
I also dislike it for C (as much as I appreciate GNU's contribution). As we all know, K&R is the one true style.
I do prefer putting opening braces at the line end in all situations though (but that also rules out a lot of other styles).
I'd like to be able to type something like:
gcc -march=x86-64-safe my_buggy_server.c
Come to think of it, that should probably be the default.In this case there's at least no silent breakage involved, but the badly written shell script that called it did not bother to check for that condition, and a fair number of heads were scratched for a while as a consequence.
https://github.com/samtools/samtools/pull/1165 https://github.com/samtools/htscodecs/pull/22
which work around limitations in the default system awk on Solaris/OpenIndiana/whatever the remnants of SunOS are called these days…
> Avoid arbitrary limits on the length or number of any data structure, including file names, lines, files, and symbols, by allocating all data structures dynamically. In most Unix utilities, “long lines are silently truncated”. This is not acceptable in a GNU utility.
... goes against MISRA C, which certainly is preferable in the domain I work, embedded systems - because dynamic allocations all over the place are a recipe for CVEs.
I can't imagine why a C compiler would remove a non-trivial runtime check though (except undefined behaviour).
[0] https://wiki.sei.cmu.edu/confluence/display/c/MSC06-C.+Bewar...
A significant number of these CVEs are related to dynamic memory allocation (double-free, use-after-free).
Probably not all are the result of that piece of advice and probably some of those memory allocations were necessary, but since this class of errors is common in C/C++, I believe it is really not a good idea to encourage people to point the gun right to their feet.
On a side note, please explain to me how this is end-user oriented in a system where the convention is that a program ends silently when everything went smoothly:
> In error checks that detect “impossible” conditions, just abort. There is usually no point in printing any message [...] Explain the problem with comments in the source.
> meaningful complexity
Not, "the most complex". If an OS that can lock down DARPA self-flying helicopter software is not meaningful enough for you....
Not a part of GP's assertion
> and how many people can check the proofs?
it's not necessary, the proofs are checked using automation. I'm directly taking a shot at this assertion:
> Static analysis tooling has demonstrated that it isn’t up to the task
What are your thoughts on SEL4, is it really a breakthrough it is made to be in success of formal verification? Is there a way for users/administrators deploying it to verify themselves authors' claims? Or is it too difficult? I am afraid the latter...
In 2004 Peter Gutmann in his thesis/book criticized the hype around effectivity of formal methods in computer security [1]. Has the situation changed?
The choice was protracted language wankery with continuous (wrong) declarations of "Soon, the compiler will make it fast enough", or actually shipping software.
The balance started tipping in the early to mid-2000s. You could, if you were very careful, write decent-sized systems with good performance in C++ at that point, and the abstractions were starting to be worth it.
And I say that as somebody who enjoys C++, and has written code in it since the late 80s. Yes, on cfront. "Horses for course" always has been, and always will be, the major driver for language adoption. That particular horse wasn't ready in the 90s.
As have I, and I say you don't seem to know what you are talking about. I've been involved in writing very large Unix and Windows applications in the 1990s (starting in the late 80s), and have had no problems that you mention.
And no, that is not correct.
Mac OS was a mix of Object Pascal (originally created by Apple), Assembly and C++.
Windows (32 bit variants) and OS/2 userspace has always been a mix of C and C++.
BeOS userspace was C++.
Symbian was full C++, including the kernel by the way.
That doesn't ring true at all.
Object Pascal was a rather short-lived project at Apple. It was only seriously used for the MacApp framework -- which was a separate product sold to application developers, not part of the core OS or development tools -- and was abandoned entirely during the PowerPC transition. Later versions of MacApp used C++.
The bits of source code I've seen for System 7 were primarily C and assembly, with some older code in (non-object) Pascal. I don't recall seeing any C++.
Namely:
- proper string and vector types (most compilers allow to enable bounds checking anyway)
- stronger rules for type conversions
- reference types for parameters
- better tooling for immutable data structures
- memory allocation primitives instead of getting sizeof wrong to malloc()
- collection library instead of reinventing the wheel in each project
- RAII
- smart pointers
- templates instead of error prone macros
- namespacing (usefull in large scale projects with prefix tricks)
string & vector types: STL, 1998 type conversion operators: 1998. mutable keyword: 1998. collection library: STL, 1998. smart pointers: STL, auto_ptr<> in C++98
I'd argue that without STL & C++98, C++ would've languished even longer. And with STL, it still took another 5 years for the compilers to be good enough.
% find ~/Downloads/System\ 7.1\ Source/ -type f -print0 | xargs -0 -n 1 basename | cut -d. -f 2- | tr '[a-z]' '[A-Z]' | sort | uniq -c | sort -rn | head -20
869 A
308 H
189 C
162 P
85 R
69 MAKE
31 M.A
28 O
11 RSRC
11 AII
...This is under-stated, IMO. It wasn't really until 2004 or even later that we had high-quality support for C++98 in GCC. LLVM wasn't available, yet. Heaven help you if you wanted to develop in C++ on OSX, since Apple's packaging of GCC was a total disaster. Step zero for developing C++ on OSX was "install GCC from FSF sources" for many years.
Even MSVC support was lagging. It wasn't until the Microsoft tools leadership got involved with C++11 that MSVC took standard support seriously. They were already prioritizing .NET in that timeframe.
Meanwhile, the big open-source desktop C++ libraries (Qt and WxWindows) still don't fully take advantage of the types and features in the standard library in 2021.
If you were developing Mac programs in C++ back then, you were probably using Metrowerks CodeWarrior.
Of course not. C++ and libraries don't go along nicely. STL is not really useful for cross boundary interop due the fact that C++ ABI is not stable.
Shipping libraries that leak STL types all over the place will only give you headache.
Besides I'm pretty confident that there are more new c++ projects created daily in 2021 than monthly at the peak of the 90s c++ craze - just on GitHub, 6/7% of C++ repos means a few million recent C++ repos.
__s and you said "You were using C++ >= 11 in 90s/00s?" to which I answered that this was not the point, because the average C++ code base isn't from the 90s/00s.
Polls of hobbyist coders, or software houses? I would be surprised if most software houses migrated to C++17 yet. Tensorflow is stuck on C++03 I think.
I'm referring to e.g. the Jetbrains and cppcon polls.
Besides even on MS-DOS with frameworks like Turbo Vision, RAII was a common pattern.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1994/N055...
In 1992, I was working on the Taligent project, probably the first major C++ operating system. (It failed.) I remember when the ARM came out---none of the compilers we had available could really do templates. Or namespaces.