15 ms·
One year of C
- strkek 8y ago> btw, did you notice how there are hardly any books, conferences or discussions about C despite being a fairly popular language? Oh, yes. When I wanted to fiddle with OpenGL (and later SDL), I was baffled to find that absolutely everything documentation-wise was for C++. EDIT: Sorry, "documentation" was probably the wrong word to use here. I meant "learning resources".
- mrpippy 8y agoProbably due to the game industry being quite C++ focused, and also Microsoft compilers’ lack of support for C99
- AlexeyBrin 8y agoHistorically the C99 support by MS was quite bad. Fortunately VS 2017 has good (not 100%) C99 support.
- faragon 8y agoWorse than bad: if I recall correctly, there was no C99 support at all until MS VS 2013. Before that you had to compile C as C++ in order to get C99-like features.
- pjmlp 8y agoTo the extent required by ISO C++14, with ISO C++17 requiring C11 library compliance. If is after all called Visual C++.
- Sir_Cmpwn 8y agoHum. That doesn't make sense, the OpenGL API is entirely C oriented and I don't know of any C++ docs.
- AlexeyBrin 8y agoThe OP probably meant most OpenGL blogs, books and tutorials. The actual OpenGL API reference is pure C.
- seandougall 8y agoIt doesn’t make sense, but it jibes with my experience. Tutorials and blog posts about OpenGL are super heavy on C++, because gaming. The official docs are C, of course, because the API is C. But the docs are rather abstruse for a beginner, and really become useful only well after you’ve gotten your bearings. (e.g. my personal beef: function names tend to be two nouns with no verb to say what the thing actually does, so you look in the docs and it says it “binds” noun A and noun B, with no explanation of what “binds” means in context, which direction the data binding goes, whether it persists, etc.)
- winter_blue 8y ago> When I wanted to fiddle with OpenGL (and later SDL), I was baffled to find that absolutely everything documentation-wise was for C++. Do you mean tutorials and the like? The official docs are pure C for both. C.f. the official SDL API doc: https://wiki.libsdl.org/APIByCategory https://wiki.libsdl.org/APIByCategory
- yareally 8y agoI ran into the same problem with the using the libraries for the C based ffmpeg (libavcodec, etc). Even worst is trying to search for information only to wind up with hundreds of entries on how to use ffmpeg with the CLI with maybe 1-2 entries related to binding to the libraries grammatically. Even ffmpeg's own documentation outside of what they generate for their API is rather sparse if you wish to do more than use it on the command line.
- jcelerier 8y ago> no actions need to happen on destruction so... you like never free, never fclose, never munmap, never pthread_join, never unlock mutexes, never close network connections or what ? Also, all of your protoypes such as sg_pipeline sg_alloc_pipeline() { should really be sg_pipeline sg_alloc_pipeline(void) { since the first one can actually be called with any number of arguments (in C, not in C++). Note also that C doesn't have return-value-optimization, hence all your struct-returning functions can possibly cause a call to memcpy (won't happen when compiled in C++ mode of course) and will generally lead to much more binary bloat than the traditional C way of passing outputs as arguments. e.g. given this trivial code in foo.c: typedef struct _foo { int x; float foo, bar; char z[1024]; // change this to 10024 to get a memcpy! } foo; void do_stuff_to_foo(foo*); foo blah() { foo f; do_stuff_to_foo(&f); return f; } A disassembly after compilation with gcc -std=c99 -O3 gives blah: .LFB0: pushq %rbp movq %rdi, %rbp pushq %rbx subq $1064, %rsp movq %fs:40, %rax movq %rax, 1048(%rsp) xorl %eax, %eax movq %rsp, %rbx movq %rbx, %rdi call do_stuff_to_foo@PLT movq (%rsp), %rax leaq 8(%rbp), %rdi movq %rbp, %rcx andq $-8, %rdi movq %rbx, %rsi subq %rdi, %rcx movq %rax, 0(%rbp) movq 1028(%rbx), %rax subq %rcx, %rsi addl $1036, %ecx movq %rax, 1028(%rbp) shrl $3, %ecx rep movsq movq 1048(%rsp), %rdx xorq %fs:40, %rdx jne .L5 addq $1064, %rsp movq %rbp, %rax popq %rbx popq %rbp ret The same thing built with g++ -O3 gives _Z4blahv: pushq %rbx movq %rdi, %rbx call _Z15do_stuff_to_fooP4_foo@PLT movq %rbx, %rax popq %rbx ret While clang (in C mode) goes for a memcpy: blah: # @blah pushq %r14 pushq %rbx subq $1048, %rsp # imm = 0x418 movq %rdi, %rbx movq %fs:40, %rax movq %rax, 1040(%rsp) movq %rsp, %r14 movq %r14, %rdi callq do_stuff_to_foo@PLT movl $1036, %edx # imm = 0x40C movq %rbx, %rdi movq %r14, %rsi callq memcpy@PLT movq %fs:40, %rax cmpq 1040(%rsp), %rax jne .LBB0_2 movq %rbx, %rax addq $1048, %rsp # imm = 0x418 popq %rbx popq %r14 retq
- Hello71 8y agoif you find yourself automagically pthread_joining, something is probably terribly terribly wrong. similarly, if you commonly need to release a mutex far away from where you acquired it, something is probably also terribly wrong.
- slaymaker1907 8y agoHow do you avoid the need for dynamically growing arrays? For instance, if you are doing any sort of IO, you often don’t know the size of the input beforehand. That either forces you to use malloc or do some strange low-level manipulations of the stack.
- jandrese 8y agoOr you read a fixed block at a time. This gets awkward if you need to stitch together the end of the previous block with the new one but it does have the advantage of being fast, especially if you fix the block size to the block size of the underlying filesystem (or a multiple).
- s_m_t 8y ago+1, maybe it is because I'm not programming the most complicated things in the world, but almost all of my data structures are fixed size arrays (or are stored in them). In my experience, dynamic memory management simply isn't needed unless you are doing something very very complicated.
- Too 8y agoHehe, the lost art of not having everything in RAM at the same time. Async APIs are getting better and better all the time but it seems like streaming APIs hasn't gotten the same love, even though it should be easier than ever now as it's just an application of async primitives.
- iforgotpassword 8y agoYeah, use the heap: realloc() is your friend. Bit often times with io you just work in chunks, e.g. read up to X KB from a socket and then write it to file.
- jstimpfle 8y agoSomething like this is all you'll need: https://gist.github.com/jstimpfle/562b2c3e9fe537e378351bb9d5be8cdb https://gist.github.com/jstimpfle/562b2c3e9fe537e378351bb9d5... Explanation: A little macro that adds the correct element size. Of course, you can opt to add it by hand as well, or put it in the run-time data structures and only set it once at initilization time. I personally think these approaches are error-prone / ugly, though. There is also the stretchy-buffer approach from Sean Barret, where you don't need to explicitly allocate bookkeeping data (capacity value in my example). That one puts the bookkeeping data and count in front of the actual data. I prefer the explicit approach, though, and I MUCH prefer having an explicit count for growing vector-like things. Because I hate when I have parallel arrays and each one has its own count. Having a shared count variable for parallel arrays is much clearer.
- tbranyen 8y agoWhy do some devs spell JavaScript and TypeScript with the incorrect casing? Not worth their time? Toy languages that aren't to be respected? Not like the rest of the post was riddled with typos to justify it.
- jacquesm 8y agoBut what did you think of the article?
- yitchelle 8y ago>> So one thing seems to be clear: yes, it’s possible to write a non-trivial amount of C code that does something useful without going mad As an embedded engineer who had written many low level code, all I had was C and assembly. I know that the higher level of abstraction you go, the amount of languages available gets bigger and bigger. I am rather bemused that he had this impression about C. I wonder how many other tech folks has the same impression??
- dvfjsdhgfv 8y agoLinux kernel developers would be bemused, too.
- cypher543 8y ago> I wonder how many other tech folks has the same impression?? I do! I've worked with C, C++, Python, Java, Go, JavaScript, Ruby, and Pascal, but for anything that isn't network-oriented or a simple CLI tool, I always reach for C (sometimes a strict subset of C++). Its distinct lack of features allows me to focus more on the problem at hand and less on the best of the hundred different ways to do something in other languages. Go is the same way, which is why I use it extensively for mid-level stuff like CLI tools and servers.
- kuschku 8y agoI've used C and Go quite a bit, and I find it a horror to write. I end up duplicating tons of code - the exact same code copied hundreds of times across the codebase, with every time slightly different changes made to it. How do you do custom data structures that need to parametrize over multiple types without duplication in C or Go? How do you do sane error handling without 90% of your code being if (...) { // handle error } or if err != nil { return err } ? I mean, just read https://git.kuschku.de/justJanne/statsbot-frontend/blob/master/main.go#L175 https://git.kuschku.de/justJanne/statsbot-frontend/blob/mast... as example. (It's a quickly hacked-together project I wrote in about 10h)
- fpoling 8y ago
- Froyoh 8y ago"It takes a lifetime to master C++"
- waynecochran 8y agoYeah when I see stuff like this I want to just go be a barista or something: https://stackoverflow.com/questions/13230480/what-does-auto-tell-us https://stackoverflow.com/questions/13230480/what-does-auto-...
- irundebian 8y agoYou can't learn C in an afternoon.
- AlotOfReading 8y agoYou can absolutely learn the syntax of C in an afternoon, or a few days at worst, if you're not having to learn to all the other concepts interesting C programs require. Much of the immense learning curve comes from th things that are "outside C", like how to synthesize high level concepts from the lower level primitives in the core language and system specific gotchas the language doesn't shield you from.
- zbentley 8y ago> You can absolutely learn the syntax of C in an afternoon, or a few days at worst That depends on what you mean by "learn". Learn it well enough to make something that works for you, on your architecture, with your toolchain? Sure. Learn it well enough to know which combinations of the syntax you (thought you fully) learned trigger undefined and wildly variable behavior in the wild or when run with other libraries/build environments? Hell no. And bugs caused by that stuff are distressingly common. That's not a "system specific gotcha". It's a huge area of skill-requiring behavior that arises directly within the core syntax of the language. Saying "you can learn C in a weekend" is like saying "you can learn to drive a car in a weekend" in reference to learning how to maneuver a car alone in a big empty parking lot. Technically true, but it'll leave you woefully unprepared for operating that car the way almost everyone wants to: around other cars, in more complicated contexts, subject to many more unpredictable factors (other people).
- chungy 8y ago"Learn C in a weekend" (or afternoon) is akin to getting accustomed to a new model of car, _with prior driving experience_. Each car has its own quirks, each programming language has its quirks. Learning C from the background of already knowing how to program is like driving a new Ford Focus off the lot and getting used to it. Learning C++, on the other hand... is expecting you to pilot a jumbo jet after your only experience was the Ford Focus.
- buserror 8y agoI made that 'reverse path' to C quite a while back, more than 10 years ago in fact. for 20 years before that, I was C++, C++, and C++. Then I gradually realised I was trying to slim down my use of the language, due to stuff I just didn't want in the codebase I was working on. Small details. Like well templates -- they were fantastically hard to track and debug at the time, and really, did they actually provide anything in the long run? Answer was... NO. they don't. Turns out it's a LOT easier to have 2 discrete functions explicitly doing the same thing than using a template. anyone will understand the scope of each if they see them; The arguments about "simplicity" doesn't exist once you get templates involved. So yes, you can 'template' in C as well using the preprocessor, but it's still ends up being MORE READABLE than a heap of scopeless C++. One thing I was fond of in C++ were stacked based objects; ie, use the constructor to save some state, and use the destructor to restore it. I think it is a lovely concept, and I still miss it -- hover it's a concept 'new hires' had problems with very often -- it was not as intuitive as it felt. It turns out an explicit save/restore is better to maintain. I wish it was different, but that got THAT feature of C++ out of the window. Anyway, long story short, I wrote zillions of lines of C++, and now I just do C. I don't have to fight with the compilers every other year for instance. Small silly example, for a million years (it felt like it!) I could write pure virtual functions declarations as ..... int blah_blah_method(some cool parameter) = NULL; -- it actually made SENSE. Then one day, someone decided it couldn't possibly be NULL -- it had to be zero as '0' or else, no compily. ^^ that is one just a silly old single example, but theres a dozen others where your 2 years old codebase suddenly isn't compiling because someone decide to shift the language under your feet. THAT doesn't happen with C. C just works. yes, there's lots of syntax sugar I WISH I would have been able to keep from C++, but ultimately, the possibility to write a huge pile of bloat is a lot harder in C than in C++. Some idiot 'new hire' won't make a hash objects for 5 elements. Some idiot colleague won't decide that the string creation class constructor shouldn't take a reference, but a copy, making the app startup take 30 seconds with ONE character '&' removal. Anyway, rant over. Regardless of what the kids says, C is nice, C is lean, C is a LOT easier to keep clean as long as the adult people using it are aware of the sharp edges :-)
- maccard 8y agoYour post is very ranty, i disagree with lots, but I think you’re flat out wrong here: > Turns out it's a LOT easier to have 2 discrete functions explicitly doing the same thing than using a template How do you write containers? I tried following a series on implementing an interpreter in c a few months ago, but gave up because 30% of the code was implementing std::vector for different types. Also, math routines definitely work better templated. Code duplication isn’t always bad but if your methods are copy and pasted with different signatures, that sucks. E.g. an interpolation method that works on double and floats. > ome idiot colleague won't decide that the string creation class constructor shouldn't take a reference, but a copy, making the app startup take 30 seconds with ONE character '&' removal. This isn’t an argument against c++, this is an argument against your co workers. The exact same argument could be made for C with removing two * signs. C has it’s fair share of gotchas thy you don’t refularly hit in c++ too - malloc requiring sizeof, not checking realloc’s return values, goto hell for resource cleanup, complicated lifetimes.. personally I’d rather have C++, warts and all, than have to deal with the “simplicity” of reimplementing a stack in every resource owner, and reimplementing vector/map for every type.
- ianai 8y agoI’m not a professional coder atm, but I learned quite a lot from “Understanding and Using C Pointers.” It’s weird knowing that I like to and can code, but being employed as a sys admin. Pretty common I imagine, as well.
- richard_shelton 8y agoI have more uses for Python than the author, but one of these uses is really obvious: Python as C code generator. Python + C is a very powerful combination: metaprogramming, special constructs etc. Basically, with Python you can get rid of preprocessor hacks and messing with templates.
- flohofwoe 8y agoAh, right! I actually use python for code generation as well, just forgot to mention it. For instance the Z80 and 6592 CPU emulators use generated code for the instruction decoder: https://github.com/floooh/chips/tree/master/codegen https://github.com/floooh/chips/tree/master/codegen
- blub 8y agoRedescovering the beauty of C seems quite similar to city-dwellers redescovering the beauty of nature: everything is rainbows and butterflies, while in reality - if you are away from the safety net of civilisation - there are hundreds of ways nature will crush you if you make even a small mistake.
- skummetmaelk 8y agoAnd then you have the rugged outdoorsmen get serious about nature and venturing into the wilderness. They plan for the worst. They bring enough supplies. They don't try to climb mountains in flip flops. They shake their fists at the city touristers leaving trash at the campsite and causing memory leaks. No garbage collectors out here. They know to respect the ecosystem flora and fauna or get ripped to pieces.
- hestefisk 8y agoSkim milk!
- tonyarkles 8y ago> No garbage collectors out here. Pack in, pack out. :)
- mmphosis 8y agomalloc, free :) in that order
- wildrhythms 8y agoThis is actually an amazing analogy.
- blobjectivist 8y agoand then there's the guy whose back in the city who knows the world is designed by aliens and that nature is artifice, all decent processor architectures are designed using dataflow HDL languages and the notion of "bare metal" nature is a delusion held by hipsters and unix greybeards
- Philipp__ 8y agoI like this blogpost. But as stated in it, “my project”. Writing C project, alone is pretty different than writing C with 1 or more persons. In highschool we had group project. Writing simple tcp/ip protocol in C. Holy shit did I see some awfull things... maybe writing C is not the bad thing about it. But maintaining could be. Simple example, you can read string from simple data file on 6,7 different ways. Yet their effects and behaviors differ severely. Not everyone knows difference in parameters and returns in scanf, fgets and gets...
- loeg 8y agoI think your experience writing C with a group might be severely colored by the group being made up of inexperienced highschoolers.
- Philipp__ 8y agoI totally agree with you on that. But the whole point was that there is much certain possibility for things to go wrong with inexperienced developers. I won’t quote the comment in the reply below, but that is the thing... edit: typing on the phone, sorry
- loeg 8y agoIn my experience, turning an inexperienced C developer loose with C++ does not result in an improvement :-).
- tomsmeding 8y agoThe thing with C is that there are plenty people that can code C and know what they're doing, but there are many more that either do not know what they are doing, or don't but think they do (which is even more dangerous). My experience mirrors yours, but I do believe these good C programmers exist.
- kqr 8y agoI'm slowly starting to believe that every single C programmer falls into the "either do not know what they are doing, or don't but think they do" category. I have yet to see a single, non-trivial C program that does not have many dangerous bugs related to language unsafety. If these mythical good C programmers exist, they certainly have never released any of their source code.
- bluescarni 8y ago> As a C++ programmer I developed my own pet-coding-patterns and bad behaviours (e.g. make methods or destructors virtual even if not needed, create objects on the heap and manage them through smart pointers even if not needed, add a full set of constructors or copy-operators, even when objects weren’t copied anywhere, and so on) Yikes.
- blt 8y agoI guess you are getting down voted for lack of content, but I agree. Those are all very bad "Java without GC" C++ practices that lead to awful code bases. Thankfully the author seems to have learned that from their experience writing C. Like the author mentions, C++ leads to overthinking which language features to use. It invites you to seek these perfect abstractions for Python readability with C performance. I think this is a big reason everyone develops their own incompatible style -- not due to passionate philosophical beliefs, just to reduce the size of the solution space.
- pmarcelll 8y agoI agree with you, mainly from the perspective of writing Rust code. When Rust was new, a lot of people said that thinking about ownership all the time is a burden, but I think it's the opposite, it gives a sort of frame that helps to build the software's core abstractions. I think in this regard C++ is much more unopinionated, which means every codebase is different. In Rust, ownership is part of the type system, so a lot of the times learning a new API can be much faster because API usage is easier to understand and this style of programming is already familiar.
- blt 8y agoyes. ownership is an extremely critical part of software design, especially for complex interactive programs.
- Entalpi 8y agoC is beautiful because it is so barebones. It does not hide data behind complex language feature that describe some runtime behaviour it is just bits and bytes moving around. A bit of a romanticed view but that is atleast the feeling I got when writing some small games witg C. Link: https://github.com/Entalpi/PongC https://github.com/Entalpi/PongC
- kakwa_ 8y ago> The dangers of pointers and explicit memory management are overrated Hummm, not my experience. The first time I ran AFL on one of my C library (parser/converter of EMF files, really easy to mess up), the result was quite frightening. IIRC, it took only 20 seconds for AFL to find 10 crashes. Ever since, first I'm more careful, second I run AFL from time to time, and it happens regularly that it catches some edge cases I was not able to see. I love programing in C, but I definitively know it's easy to make mistakes in it.
- phendrenad2 8y agoWhat's AFL?
- cytzol 8y agoI think it’s American Fuzzy Lop, a fuzzer that’s good at finding bugs in your code: http://lcamtuf.coredump.cx/afl/ http://lcamtuf.coredump.cx/afl/
- deleted 8y ago[deleted]
- kakwa_ 8y agoAmerican Fuzzy Lop. http://lcamtuf.coredump.cx/afl/ http://lcamtuf.coredump.cx/afl/ And no, it's not the rabbit ^^. It's an 'intelligent' (as opposed to purely random) fuzzer that is quite good at finding edge cases (it's a very/too short summery, please read the link for more details).
- josephg 8y agoI have that experience in pretty much every language, the first time I run a fuzzer on my code to check an invariant. I'm honestly surprised fuzzers aren't more widely used - they're far more effective per line of code compared with classic unit test suites, and easier to extend. I'm not sure I've ever run a fuzzer on virgin code and not found new bugs. Even when the code in question already had allegedly comprehensive unit tests. The one time I tried AFL, I didn't find any new bugs beyond the embarrassingly large number my own fuzzer had already pointed out. But I agree with your point. Some double-digit percentage of bugs in a C library will be memory related, with all the remote execution implications that brings. This is arguably not a big issue for games or webassembly code. But for networked services it seems increasingly irresponsible now that Rust, Pony & friends are maturing.
- ufo 8y agoDoes anyone know more examples of C APIs where the user is responsible for allocating data and where all the functions only "borrow" pointers? Is getting rid of malloc/free worth the loss of information hiding?
- kccqzy 8y agoPretty much the vast majority of the API out there? Only relatively new ones like asprintf or getdelim do memory allocation for you. I don't understand your remark about information hiding. How does the difference between returning an owned pointer and borrowing a pointer concern information hiding?
- ufo 8y agoIf your function operates with a pointer to a struct you don't need to put the contents of the struct in the header file. You can simply declare the struct with struct mystruct; and then use `mystruct*` in the function prototypes. I think in C++ this is known as the PIMPL pattern. I was also asking more about user-defined libraries than about the standard library...
- frankzinger 8y agoOpaque types do not force you to do the allocation in the library. my_lib.h: struct my_struct; size_t my_struct_size(void); #define MY_STRUCT_MAX_SIZE 512 #define MY_STRUCT_VAR(name) \ char name##_buf__[MY_STRUCT_MAX_SIZE]; \ struct my_struct* name = name##_buf__ void my_construct(struct my_struct*, int, float); my_lib.c: struct my_struct { int i; float f; }; size_t my_struct_size(void) { return sizeof(struct my_struct); } void my_construct(struct my_struct* ms, int i, float f) { ms->i = i; ms->f = f; } user.c: // On the heap struct my_struct* ms = malloc(my_struct_size()); my_construct(ms, 123, 456.0f); // On the stack MY_STRUCT_VAR(ms2); my_construct(ms2, 123, 456.0f);
- ufo 8y agoDo you know of any libraries that do this? When I tried it here GCC complained about `ms2 = ms2_buf__` being an assignment between incompatible pointer types. That sounds like an easy way to get into trouble and undefined behavior.
- slavik81 8y agoThis could also be viewed as a comparison between two different styles of C++.
- hawski 8y agoWith C99 it's not that obvious. Compound literals are outside of C++ standard. However GCC for example supports them, but a bit differently [0]. $ cat foobar.c #include <stdio.h> struct foo { int x; int y; }; int foobar(struct foo *f) { return f->x + f->y; } int main(int argc, char *argv[]) { (void)argc; (void)argv; printf("%d\n", foobar(&(struct foo){10, 20})); return 0; } $ gcc -Wall -Wcast-align -Wextra -pedantic -std=c99 foobar.c -o foobar && ./foobar 30 $ g++ -Wall -Wcast-align -Wextra -pedantic foobar.c -o foobar && ./foobar foobar.c: In function ‘int main(int, char**)’: foobar.c:17: warning: ISO C++ forbids compound-literals foobar.c:17: warning: taking address of temporary 30 $ # taking address of temporary means that it's undefined behavior [0] https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html
- slavik81 8y agoThe stated he was only using the subset of C99 that could compile as C++.
- pmarcelll 8y agoI thought when people say memory safety in C is a problem, they usually mean in a larger codebase with hard to define API boundaries and with multiple programmers that can't handle the complexity of the code, which results in a team that can't find a single person that is familiar with the whole codebase.
- 01001 8y agoAs a C coder I find myself trampling over my own memory a lot. Say you have a pointer somewhere that points to a struct, and then once every 10 million iterations of a set of 20 functions that pointer gets written over by a string that lacks a NULL terminator occasionally. So your program crashes in a completely random place that has nothing to do with the origin of the bug. That's the problem with memory safety. But the lack of memory safety is also very powerful, you can malloc a chunk of memory and then use it in extremely creative ways, you really see some peoples genius shine when you read their source code, in a way that I haven't been able to see with other languages.
- megous 8y agoThis is soved by knowing the destination size and using functions that respect that and never assume the size of an input will not be larger. (unless proximity of something that would assure the size of input is close enough to where you're making the assumption about it in code, but still you'd be taking risks, especially if it's not your code, but some foreign library call) It's the same with web programming. You always escape on the output, or just avoid escaping by using proper API (el.textContent = 'something').
- zippitydoodah68 8y agoThat's why you need an ADT for strings. I've seen this problem (and experienced) this problem multiple times. Any char array needs explicit termination based on use.
- opcenter 8y agoVery cool read and a lot of your happy discoveries are similar to reasons why I like coding in Go, especially your "Less Language Feature ‘Anxiety’" section. No guessing about how to do something, there's generally only one way to do something.
- sriram_malhar 8y agoAs someone said, "C is an improvement on its successors"
- fanf2 8y agoTony Hoare, “hints on programming language design”: >> The more I ponder the principles of language design, and the techniques which put them into practice, the more is my amazement and admiration of ALGOL60. Here is a language so far ahead of itst ime, that it was not only an improvement on its predecessors, but also on nearly all its successors. << http://flint.cs.yale.edu/cs428/doc/HintsPL.pdf http://flint.cs.yale.edu/cs428/doc/HintsPL.pdf
- sriram_malhar 8y agoAh, nice. Thank you. I knew I had seen it somewhere.
- jstewartmobile 8y agoThe wonderful thing about C is that bad coding can't hide. The programs blow up early and loudly. In safer languages, the memory bombs go away through garbage collection / safe pointers / borrow checking / etc, but all of the uglier and quieter mistakes are still very much there. Knuth and von Neumann took the same approach to PRNGs back in the early days...
- kqr 8y ago> The programs blow up early and loudly. Loudly, sure. Early? I wish that was the case. Heartbleed and other high-profile exploits rely on this sort of thing being able to pass unnoticed.
- jstewartmobile 8y agoYou got me, fair-and-square! Speaking holistically though, most of the programs I enjoy using on a daily basis were written in either C or C++. Safer languages should have a tremendous edge here, but the proof has not made its way into the pudding. Just think C works as a kind of "high-pass" filter for programmers--and is net positive to overall software quality. Memory issues? YMMV
- yitchelle 8y agoWell, the ones that blow up quietly are the ones that you must be really careful about. Imagine a slow memory leak that would only crash the system after a few months on continuous usage, I could throw up just thinking about it :-)
- dpc_pw 8y agoFor a small, one person project you can use absolutely any language and feel great about yourself and the language. It's like a stroll in a park - you can do it in any shoes, or even barefoot. Where language matters are thousands or million lines of code projects, with multiple teams and people of varying experience and abilities, coming and leaving. With stupidly short deadlines and changing business requirements. With liabilities, support, maintenance, budget, time-to-market, etc. Then it's like climbing Mt. Everest, in a snowstorm, with limited supplies and low team morale. This whole article is just "mom look, I can walk". I come to HN to hear a "I've survived hell and here is how my shoes did" story.
- nevi-me 8y agoThe author makes an important point about having a list of languages to choose from. We are working on a JVM-based project at work. We chose to use Kotlin because the initial team was intermediate programmers who didn't have that much experience. When we got an MVP out, and some clients willing to pay for the solution; we got some Java devs involved. The guys have only known Java 6 and 7. They are struggling around with Kotlin, not because it's difficult, but because they only know "The Java Way". Sadly also, they've been stuck in J6/7 for so long that they don't know Streams or Lambdas. For people making their living from Java, that's dangerous self-extinction. Their software architect is even worse. Ignorant guy who lives in a rock, if they don't understand something or have never heard of it, it's wrong or useless. We're working on a greenfield project, and the guy wanted to write a REST proxy on top of gRPC because he thinks clients won't like us having ports exposed internally. I nearly took him for his salary when I told him that *://localhost is only visible to the local machine. He bet me his salary that he could access a service on the server even if it's listening on localhost. I was gracious when it came time to pay up. Anyways, I wish the guys were the exception, but I've seen many guys in their 30's who still think Oracle Inc. is where the sauce is. My advice: learn something new every once in a while. The author found that C was better suited for some things than C++. That's a powerful statement to make, something I've learnt a lot over the years when I pick up a new language.
- deleted 8y ago[deleted]
- pjmlp 8y agoYou got a point, but being stuck into older language versions is quite common on enterprise shops. If the server they have to take care of only runs language version X, that is what they care about, after work there is another life totally away from computers. When time comes for language X + 1 version to be replaced on the deployment system, then there will be one week of web based trainings to learn whatever is new in version now available on the IT development images and that is it. Yes, there are lots of modern companies out there, but there are tons of them, specially when software is not their core business where development improvements come at snail speed, if at all.
- 8y ago
- deleted 8y ago[deleted]
- IloveHN84 8y agoWhy not C11 instead of C99? It brings even new better safety
- Too 8y ago> Writing C++ classes often involves writing constructors, destructors, assignment- and move-operators, sometimes setter- and getter-methods… and so on. This is so normal in C++ that I only really recognized this as a problem when I noticed that I didn’t do this in C. POD containers don't ever need manually written copy/move/assign constructors or destructors. In fact hardly anything except resource managing classes need them (eg if you are implementing shared_ptr or mutex yourself). If you are writing your own copy constructor without knowing why, your code is not only needlessly bloated but also most likely broken. Follow "rule of zero" instead.