29 ms·
Its really wild, as a person coming from other languages who has written maybe ten lines of C in his life that the functions that seem to be massive footguns in
by paultopia 6y ago
Its really wild, as a person coming from other languages who has written maybe ten lines of C in his life that the functions that seem to be massive footguns in C are, like, "format a string" or "get time in GMT." That's... really scary.
- ironmagma 6y agoYeah, there is a culture of complacency in C probably owing to the enormous historical baggage of legacy code that has to be supported and the blurred line between stdlib and system call.
- Spivak 6y agoI mean on Linux you're not encumbered by this because the syscall api is stable but in practice most GNU/Linux distros assume glibc. You can't correctly resolve a hostname on Linux without farming out to glibc -- hell even the kernel punts to userspace for dns names but you can technically ignore it if you want. On BSDs and macOS you're always SOL because the syscall api isn't stable and only the C wrappers are.
- dangerbird2 6y agoc standard library doesn't really relate directly to system calls (at least in modern os'es). In particular, the stdio.h functions are buffered by default, while their system call analogues are not. For unixes, system call wrappers are typically found in <unistd.h>, not the "official" c standard library
- freedomben 6y agoI disagree completely. Devs who use C are the least complacent about security in my experience. The problems are from previous eras before they knew about many of these things. A ton of people in modern languages couldn't name a single dangerous function, though they do exist in every language. You'd be amazed at how many race condition vulns result from TOCTOU errors just in authentication, or checking for the existence of a file before opening it, etc. It's absolutely true that decades ago the C community was complacent, but it's not true now. Source: I taught secure coding in C/C++ in the 00s.
- IgorPartola 6y agoWhat you said. Nobody is complacent. Anyone who thinks the Linux or OpenBSD (etc.) kernel developers take the lazy way out is talking about a thing they know little about. I do think better languages than C exist and maybe could even be used as a basis for new systems. But I have yet to see a mature OS that’s as secure and as performant as these. Closest might be the chips I’ve seen that have an embedded Java byte code interpreter.
- ironmagma 6y agoI agree in principle but think these security-focused C developers are focusing on the trees for the forest. Every developer having the responsibility of cultivating their own pet list of banned functions is, frankly, NOT the way to achieve security. Those things need to be enforced at the widest level possible (OS, or language) to have the needed effect.
- IgorPartola 6y agoTwo ways to look at it. If I told you that your computer or phone could run the same OS and all the same programs but at 1/10th of the speed so that certain classes of bugs could be eliminated, would you make that switch right here and now? I don’t mean theoretically I mean the device you are looking at right now. If not, would you do that in a year? On the other hand, Moore’s law and all that. Computers will get faster over time so at some pint we might not care. And the opposite of my question is also true: if you could switch to a faster OS written in assembly, would you (assuming all functionality stays the same), knowing certain classes of bugs are more likely? It seems to me that the cost of these kinds of bugs is amortized such that it is cheaper to use C than to switch. Expressed in those terms, we will only switch to a different language for all our systems stuff when the cost of the rewrite and the cost of the performance penalty are clearly and significantly less than the cost of the bugs we are likely to expedience.
- paavohtl 6y agoYou're ignoring the fact computer science has advanced since the 1970s when C was created. C is not full of footguns because that's the only way to build a fast language, it's unsafe because it's old and full of legacy baggage. Modern systems languages (primarily Rust, and to a lesser extent Zig) are on par with C in terms of performance, yet eliminates entire classes of potential safety bugs. Rewriting of course has a (major) cost, but I don't think the argument that using C is somehow inevitable in order to get fast code holds any water.
- dangerbird2 6y agoIt's not really complacency: it's that the standard library is intentionally minimalistic to maintain portability and backwards compatibility. If you want sensible string handling, it's usually best to use a high level utility library like GLib(https://developer.gnome.org/glib/stable/ https://developer.gnome.org/glib/stable/) or Apache Portable Runtime(http://apr.apache.org/ http://apr.apache.org/), or roll your own safe string type (preferably non-null terminating)
- yxhuvud 6y agoNo, if you want sensible string handling, the sane choice is usually to choose to use a language that is not C. Not always, but definitely usually.
- IgorPartola 6y agoIt’s not hard to have strings like you do in other languages in C. It is hard when you treat char foo[] as if it was a string object like you have in JavaScript or Java or Python. C strings are just chunks of memory terminated by \0. They can still be mildly useful that way but if you actually want to do string operations you need to use a library designed for the problem (variable length, storing length with the object, Unicode support, etc.). Problem is that most people don’t start with such a library so they end up doing the hard work themselves in an ad hoc manner. You can’t fuck up String(“Hello “) + String(“world”) but you can definitely fuck up strcat(buf, “Hello “); strcat(buf, “world”);.
- Ar-Curunir 6y agothere's nothing inherently unportable about strings though.
- ironmagma 6y agoWhy do you need backward compatibility with a compiled language? Other languages like Rust and JavaScript (even) avoid that with a pragma tag on the source.
- 6y ago
- munchbunny 6y agoThe decision to make C strings null terminated with implied length instead of length + blob continues to trip us up, 30+ years later. There's a good reason the "safe" versions of those functions all take length parameters. But way back when this approach was chosen, I don't think the state of the art could fully predict this outcome. But also, "strings" and "time" are actually very complex concepts, and these functions operate on often outdated assumptions about those underlying abstractions.
- jrimbault 6y ago30+ years -> 50+ years Funny mind thing to forget to increment counters each year.
- Blikkentrekker 6y ago> But also, "strings" and "time" are actually very complex concepts, and these functions operate on often outdated assumptions about those underlying abstractions. Even in safer languages such as Rust, there are often quæstions as to why certain string operations are either impossible, or need to be quite complicated for a rather simple operation and are then met with responses such as “*Did you know that the length of a string can grow from a capitalization operation depending on locale settings of environment variables? P.s.: In fact, I would argue that strings are not necessarily all that complicated, but simply that many assume that they are simpler than they are, and that code that handles them is thus written on such assumptions that the length of a string remain the same after capitalization, or that the result not be under influence of environment variables.
- throwaway09223 6y agoMany of C's problems relate to string handling. These are all legacy functions which have been replaced with safe alternatives many decades ago. strcpy() was replaced with a safer strncpy() and in turn has been replaced with strlcpy(). The list is a ban of the less safe versions, where more modern alternatives exist.
- ChrisLomont 6y agoThese still lead to lots of bugs via off by one errors on lengths or other buffer misuse.
- cestith 6y agoStill, unless you're writing something that has to be very low-level all the way through, it's better to use a string-handling library than the stdlib tools for strings.
- stefan_ 6y agoThe first thing you do is not use any strings. You'll be amazed how much you can get done in languages that aren't so obsessively centered around stringified programming.
- derefr 6y agoYes, sure, write Unix CLI plumbing tools without strings.
- pjc50 6y agoUntil you want to communicate with the user, filesystem, or web.
- Animats 6y agoIt was a design decision of QNX that the kernel never uses strings. Everything the kernel handles is fixed length, except messages, and messages go from one user process to another. The kernel does not allocate space for them. I think they go that right. There's a QNX user process that's always present, called "proc", which handles pathnames and the "resource managers", programs which respond to path names. But that's in user space, and has all the tools of a user-space program.
- cperciva 6y agoA better way of looking at it is that functions which expose very simple operations were among the first ones to be placed into the standard library -- and consequentially are the least well thought out.
- jchw 6y agoUnfortunately, much of the pain with C surrounds dealing with strings. It’s been a bit of a theme on Hacker News for the past few days, but it’s actually a pretty good spotlight on something I feel is not always appreciated - strings in C are actually hard, and even the most safe standard functions like strlcpy and strlcat are still only good if truncation is a safe option in a given circumstance (it isn’t always.) (~~Technically~~ Optionally, C11 has strcpy_s and strcat_s which fail explicitly on truncation. So if C11 is acceptable for you, that might be the a reasonable option, provided you always handle the failure case. Apparently, though, it is not usually implemented outside of Microsoft CRT.) edit: Updated notes regarding C11.
- masklinn 6y ago> Technically C11 has strcpy_s and strcat_s "Theoretically" is the word you're looking for: they're part of the optional Annex K so technically you can't rely on them being available in a portable program. And they're basically not implemented by anyone but microsoft (which created them and lobbied for their inclusion).
- jchw 6y agoI didn’t know that it was Microsoft that lobbied for them; that perplexes me since I thought Microsoft’s version of them were a bit different (for example, I think C11’s explicitly fail on overlapping inputs where Microsoft specifies undefined behavior) and because Microsoft didn’t bother supporting C99 for the longest time. (Probably still don’t, since VLA was not optional in C99, IIRC. I think Microsoft was right to avoid VLA, though.)
- SavantIdiot 6y agoIf you list the languages you use, I'd be happy to point out the "footguns" in each of them. For all the warts on C, there really is no language that can compete for what it has accomplished over ~50 years. Recall that during the rise of C, people were writing machine code on punch cards. Assembly -> Machine code has far more footbullets than C, it is a tradeoff between hand holding and tiny fast code. Wow, this blew up. To all the people popping off about how great other languages are, tell me: when will we see the Unreal Engine written in Python, or Pascal, or Algol, or Rust, or Go... the next big step is WebASM (or .cu), and that's way more footbullet-y than C. And what is the native language all of your sub-30 year old interpreted languages were written in? Thank you!
- tester756 6y agoJust because I want to know people opinion's (+they may be more than happy to shit on C#:) C# But please, nothing about using unsafe.
- maerF0x0 6y agoNot that I dont believe there are any, but I'd love to hear your perspective... Go (golang)
- crimper 6y agochannel programming and the races caused by closing channels. channels seem nice and easy until they don’t. the whole var/:=/= assignment combined with the error handling style and the shorthand is another one
- maerF0x0 6y agoyeah the lack of determinism in selecting a channel can be tricky for causing bugs where order matters. Luckily in smaller cases you're likely to encounter them as flakey tests (eg 1/2 the time) select { case <-ch1: case <-ch2: }
- 6y ago
- IgorPartola 6y agoThis is a lot like how in JavaScript you have footguns like the with statement or in Python 2 where you have Unicode issues, etc. I am sure we could definitely a new C standard that excludes these functions as obsolete, but the linked header file is a pretty sensible interim solution. C is an old language and it’s kind of amazing that code written 30 years ago can still by and large be compiled by a modern compiler. Ever try to run 3 year old React projects using today’s React? :)
- ggregoire 6y ago> in JavaScript you have footguns like the with statement I've been coding in JS on a daily basis for more than 10 years and today I learned there is a `with` statement in JS. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... Edit: well, seems like it's been deprecated/forbidden since ES5 (2009), so it makes sense I've never seen it.
- GordonS 6y agoAnd me around 20 years - also never even heard of the `with` statement! I think to qualify as a footgun, people actually need to be using it in the real world.
- javbit 6y agoIt should be called something like appendixgun then because you don't use it but it still has a chance of causing needless suffering and pain.
- astrange 6y agoThe appendix is a reservoir of gut bacteria in case you lose yours in an infection or by taking too many antibiotics.
- IgorPartola 6y agoI have seen it in the wild. I first learned of it from Douglas Crockford’s JavaScript the good parts. He also had some things to say about the new keyword and prototype inheritance and how we should stop using them. Ironically while he was dismissed on that suggestion then, VueJS has pretty much implemented exactly what he has in mind in their V3.
- deleted 6y ago[deleted]
- oleganza 6y agoNotice that it's a giant PITA to work with any variable-length data. Because language lacks adequate means to abstract away safe fast memory access with generic types, RAII and borrow checkers. Comparing to C, both C++ and Rust (very different beasts) feel like pals of JavaScript: basic operations with dynamic strings and arrays just work™.
- Camillo 6y agoMany of the problems with C descend from a common root, the decision to use bare pointers (memory addresses) as the basic way to refer to strings, arrays etc. If they had used a {pointer, size} pair instead, it would have avoided all of these string problems, most buffer overflows, even the GTA Online loading problem that was on HN recently.
- Animats 6y agoPascal, which had sized strings, was in wide use before C. Many people, including Bill Atkinson, who wrote many of the original Macintosh applications, thought C was a step backwards. Pascal, to save one byte, limited strings to length 255. Bad decision.
- lelanthran 6y ago> Pascal, which had sized strings, was in wide use before C. Many people, including Bill Atkinson, who wrote many of the original Macintosh applications, thought C was a step backwards. Sure, but parent wasn't saying "it was not possible", they said "It was too expensive". And sure enough, the market drifted to the cheaper solution: you could run slightly more applications if your OS and applications were all written in C than if they were written in Pascal, Modula, etc.
- cb321 6y agoFor what it's worth, while what @Camillo says is both true and important, people usually do not mention the trade offs involved or why that decision was attractive at the time. These days (ptr,size) is probably 16 bytes -- longer than almost all words in the English language (the scrabble SOWPODS maxes out at 15). A pointer alone is 8B. Back at the dawn of C in 1970, memory was 7..8 orders of magnitude more expensive than today..(about 1 cent per bit in 1970 USD). (Today, cache memory can be almost as precious, but I agree that the benefits of bounded buffers probably outweigh their costs.) 8B pointers today are considered memory-costly enough "in the large" that even with dozens of GiB machines common, Intel introduced an x32 mode to go back to 32-bit addressing aka 4B pointers. [1] There are obviously more pointers than just char* in most programs, but even so. Anyway, trade offs are just something people should bear in mind when opining on the "how it should be"s and "What kind of wacky drugs were the designers of language XYZ on?!!?". [1] https://stackoverflow.com/questions/9233306/32-bit-pointers-with-the-x86-64-isa-why-not https://stackoverflow.com/questions/9233306/32-bit-pointers-...
- frob 6y agoAs someone who learned C as their first language, strings in every single language after that have felt like cheating. "What? You mean I can type an arbitrary string and it works? I don't need to worry about terminators or the amount of memory I've allocated? You can concatenate two strings with +?!? What is this magic?"
- macintux 6y agoYeah, every time I decide to play with C for nostalgia's sake, I immediately get hung up on just how painful everything is, especially strings. I still love C, but I'd do my best not to have to write anything serious with it again.
- unbalancedevh 6y agoIt always makes me wonder if there's some hidden overhead that I'm absorbing. When I program in C I feel like I know a lot better what the generated instructions will be. Using higher-level languages for embedded programming where resources are tight makes me uncomfortable.
- gpanders 6y agoBasically every (non-C) string implementation in existence has to do dynamic memory allocation under the hood, which is hidden from the programmer. That’s the overhead.
- 1f60c 6y ago> When I program in C I feel like I know a lot better what the generated instructions will be. If you don't know about the Compiler Explorer, definitely check it out: https://godbolt.org https://godbolt.org
- Gene_Parmesan 6y agoIn addition to the overhead from dyn alloc and the GC as someone else mentioned, there is also the size overhead that comes with every object in an OO language. The obj overhead for Java is JVM-dependent, but I believe it to be somewhere around 16 bytes. A mostly unrelated stackoverflow post I found[0] states that an empty standard string in Java occupies 40 bytes due to the normal object overhead and overhead related to the internal byte array for the char storage. Obviously what you gain in return is convenience in programming as well as runtime-enforced safety from buffer overflows. Whether this is worth it depends on what you're doing. In general, you're definitely absorbing overhead with any managed lang, although it need not be hidden. The specifics should be documented somewhere for whatever platform you're using, and most GCs are pretty tuneable nowadays. [0] https://stackoverflow.com/questions/56827569/what-is-an-overhead-for-creating-java-objects-from-lines-of-csv-file https://stackoverflow.com/questions/56827569/what-is-an-over...
- draw_down 6y agoNow ponder how many people find that state of affairs acceptable but also think JS is a terrible garbage language that idiots like.
- Communitivity 6y agoI remember an entire lecture about the use and abuse of sprintf and related functions as a means of exploit. Yeah, when you delve into the internals of C you find things that are terrifying if you are concerned about reliability, security, or performance. The same is true though for many languages. The problem is, as is often the case, the Iron Triangle: good, fast, cheap - pick two. Different sections of the language are written by developers under different constraints and pressures, which leads to different choices. In my experience every language implementation has at least one area that was done quickly for expediency or done poorly because no one else was able to (or wanted to) work on it.
- kazinator 6y agogmtime is just not thread-safe that's all, since it returns a static structure; gmtime_r is not banned.
- syncsynchalt 6y agoThanks, I am now a decade out of the C game and I was wracking my brain on what the problem with gmtime would be. My best guess was dodgy is_dst portability /shrug
- EdwardDiego 6y agoYeah, found this which explained it for me :) https://lgtm.com/rules/2154840805/ https://lgtm.com/rules/2154840805/
- matheusmoreira 6y agoYeah, because of NUL-terminated strings. They cause so many problems it's not even funny. Even something simple like computing the length of the string is a linear time operation that risks overflowing the buffer. People attempted to fix these problems by creating variations of those functions with added length parameters, thereby negating nearly all benefits of NUL-terminated strings. Why can't we just have some nice structures instead? struct memory { size_t size; unsigned char *address; }; enum text_encoding { TEXT_ENCODING_UTF8, /* ... */ }; struct text { enum text_encoding encoding; struct memory bytes; }; All I/O functions should use structures like these. This alone would probably prevent an incredible amount of problems. Every high-level language implements strings like this under the hood. Only reason C can't do it is the enormous amount of legacy code already in existence...
- guerrilla 6y agoThat would be nice. You hit on the other hell with C strings: modern encodings where wchar_t and mb* are useless and replacements essentially don't exist yet with char8_t, char32_t etc. Then there's the locale chaotic nonsense [1]. A new libc starting fresh would be nice. 1. https://github.com/mpv-player/mpv/commit/1e70e82baa9193f6f027338b0fab0f5078971fbe https://github.com/mpv-player/mpv/commit/1e70e82baa9193f6f02...
- matheusmoreira 6y ago> A new libc starting fresh would be nice. Agreed. I want to make something like this on top of Linux one day. I discarded the entire libc and started from scratch with freestanding C and nothing but the Linux system call interface. Turns out the Linux system call interface is so much nicer. https://github.com/matheusmoreira/liblinux/blob/master/examples/hello-world.c https://github.com/matheusmoreira/liblinux/blob/master/examp...
- rtpg 6y agoThe string stuff is kind of the original sin, but to be honest almost all programming environments have massive footguns when it comes to times/dates. Python's datetime story is _extremely_ painful to deal with. Try doing .... I dunno, anything apart from getting the current time and doing an ISO format of a Javascript Date object. I think stuff has kinda gotten better, but while Unicode had emoji to kinda save the day, dates never had this moment and we're still suffering through major messes on a daily basis because of it.
- AaronFriel 6y agoPython's dates are very unlikely to cause quadratic or exponential performance dips, segfaults, or remote code execution vulnerabilities. (And JS now has Date#toISOString, since ES5.) C's string manipulation functions are a regular source of the worst vulnerabilities in software. Even if they're in the same category of legacy cruft, they're not even remotely in the same magnitude of consequences.
- rtpg 6y agoI think you misread my message, I was saying that "time stuff is messed up everywhere", not "python's time stuff is like C's string stuff". The C string stuff is a mess. I was also saying that JS dates _can_ generate ISOStrings. But good luck doing any serious manipulation without issues. Hell, there isn't even a `strftime` equivalent for JS dates! And so much stuff ends up going through locales that you can't rely on it for machine transformations. I would be careful about ascribing the quadratic perf discussion to be a C thing though.... I find loads of "accidentally quadratic" stuff in loads of languages all the time. People are really bad about this (lots of confusion between "this is built-in to the data structure" and "this is cheap"). Anyways, yeah. Strings are uniquely awful. Other C APIs suffer from issues, but I find those issues are on par with other language thing. Granted, it's sometimes _because of C_ that other languages suffer from the issues (by relying on C layers for the logic).
- jxy 6y agoThat's an unfortunate result of backward compatibility. If it were Python, it would just become v2 and tell people to suck it up.
- ChrisRR 6y agoStrings are half the reason I never recommend someone learns C as their first language. Python is much easier, and then you can pick up C afterwards when you've got a better baseline knowledge I've seen the same question posted way too often by beginners to C. "I've created a char*. Why am I getting <random fault> when I try to write to it?"
- 0xbadcafebee 6y agoWell that's input validation for ya. It's not enough to say "give me a string", or even "give me a file path", and then only check that it has ASCII characters. You have to validate that this input could conceivably be a file on this system that someone would use. "../../../../../../../../../../../../../../../../../../../../etc/shadow" is not a file someone would ever reasonably want to access. But is there an easy way to look for nonsense paths without potentially limiting functionality, or writing more code than you wanted to? Nope. The same footgun exists in all languages; C's design just has a hair trigger.
- oleganza 6y agoThat example is typical "confused deputy" security vuln irrespective of the language, not a "validate input" one. Meaning, the typical unix interface to the filesystem is such that it's hard/impossible to express "i'm only having access to this folder and interested in paths within that folder". `chroot` is too dramatic sandboxing that cannot be used for all use cases. BTW, in macOS there are "secure bookmarks" (see NSURL docs) that are effectively capability tokens: when user drags a file, or selects it in an Open File dialog (which runs isolated from the app), the kernel creates an app-specific token that grants access to that file to the app, so it can access it beyond its sandbox.
- beej71 6y agoWhile it's true that there are a lot of unsafe functions in C, it's not really a mistake. C is a fundamentally unforgiving language. You just have to accept the fact you're driving a naked supercar with no seatbelts. It's easy to survive: just don't crash. :) And, functions aside, it's trivial to write a C program that bombs out without calling any functions at all, safe or otherwise. It's a language from a different era, for sure. Back then no one had the computing power to build Rust. And remember that before C, they were writing Unix in assembly language. So sprintf() was a big step up!
- anikom15 6y agoWhat’s scary is programmers assuming any function as being safe. C programmers don’t trust anything, and they’re better programmers for it.
- jhanschoo 6y agoThis statement is not even wrong. Good programmers of any language are aware of the footguns in their language and the things their compilers assume. Bad programmers don't. C has unsafe basic functions because the programs written then were much simpler, and this sufficed. There's decades of PL research resulting in new languages that give better guarantees than C, allowing you to worry less about wrestling with the language and more on your business logic. > C programmers don’t trust anything, and they’re better programmers for it. By that dime, frontend JS programmers trust things even less than C programmers, and they're even better programmers for it. \s (in reality, FE JS devs mainly wish that browser environments were more consistent and predictable, and would disagree that they are better developers because of it).
- huhtenberg 6y agoAll this stems from C strings being zero-terminated. This in turn stems from the dedicated CPU support for working with zt strings that traces all the way back to PDP-11. So what C does here is exactly what it has always been doing - it provides a thin wrapper of the existing hardware functionality. The variadic arguments are of the same nature - they basically allow for manual call stack parsing, again something that is a level down from the application code. It's also easy to see how an API like sprintf and scanf came about - someone's just got tired of writing a bunch of boilerplate code to print a float with N decimals aligned to the left with a plus sign. So they threw together a function call "spec" (the format string), added a call stack parsing support (va_args) and - voila - a beautifully concise print/scan interface. It is a very clever construct, you've gotta give it that. The flip side that it required people to pay close attention how they use it, which wasn't that bold of a requirement back then. But as time went on, the average skill of C programmers went down, their use of the language did too, so more and more people started to step on the same rakes. So, here we are. Zero-terminated strings are forbidden and va_args calls are nothing short of the magic.
- klingon79 6y agoI wonder if these headers were applied to the majority of C projects in, let’s say, all projects that were part of a Linux distribution- how much would fail to compile. My guess is: a lot.
- cesaref 6y agoI think the key is to understand the historical context of C, what it was competing with, and what concerns people writing C had. Compared to the alternative (straight assembler) at the time as a systems programming language, C is a massive step up. Also, the UNIX way was independent processes, so the APIs did not need to be thread safe, as there was no threading in the target architectures. Now given the massive amount of existing C out there from the time of such architectures, you either have to move the API and language on to make it incompatible with existing code, or support the old baggage. The language has kept compatibility, and in this case, the github peeps have deprecated APIs using macros, so it's a reasonable approach. An alternative approach would be to move the language on, but by it's nature it won't be compatible with C, so you give it a new name. You call it things like go, or rust, or swift. These are all C with the dangerous bits removed. It'll be interesting in 40 years time to see if people are having the same conversation about these languages - 'OMG, how did people write stuff in rust? It can't cope with [insert feature of distributed quantum computing]. It's really scary'
- da39a3ee 6y agoThis is git, not github.
- johnnycerberus 6y agoI wouldn't say that Go is an alternative approach. I mean, what's the difference between Go and Java AOT with Graal? But Rust is truly an alternative to C/C++.
- kevincox 6y agoIn many ways Go is the safer more productive language for C lovers. There are only a couple major differences between the two languages so I think that it is one of the easier places to convince C lovers to move to. I have met a number of strong C proponents and they all seem to be relatively OK with Go, especially compared to C++, Rust and Python. The major differences in my head are: - Garbage Collection - Interfaces There are some other more minor things like defer and the built-in generic types but many C programmers already had macros to implement similar things. So sure, Go doesn't solve all of the problem spaces that C does. But if you are in a problem space where you don't need see (or another low-level systems language) Go may be a middle ground to move C programmers to.
- HelloNurse 6y agoWhat you call "format a string" is actually "begin a perilous expedition into uncharted memory".
- bregma 6y agoC is a well-stocked kitchen of a language. Unfortunately, it is riddled with sharp knives that can cut you, open flames that can burn you, gas that can smother you, water than can drown you and food that can make you sick if you prepare it incorrectly. Some react to this potential safety threat by banning the use of knives, stoves, sinks, and food from a kitchen. Fortunately most attempts at safety just require having a microwave to prepare the frozen pizza or Uber Eats delivery.
- JdeBP 6y agoI was hoping that someone would have already pointed out that this is not quite correct phraseology, as the qualifier "old ways to" has to be inserted: e.g. "old ways to get time in GMT". The "new" ways have been around for nigh on 30 years in some cases, and aren't really "new" now. I've been using localtime_r() for almost that long, for example. Coming from another language, don't be fooled into thinking that what you are looking at in these lists is the current state of the art for the language.
- deleted 6y ago[deleted]