TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

The case for a modern language

206 pointsby bshanksover 3 years ago

18 comments

prirunover 3 years ago
PL&#x2F;I, created in 1964, had strings. Real strings, where the compiler knows the length even when it gets passed around and is declared char(*) var in the receiving function. You can&#x27;t have buffer overflows because the compiler and runtime know every string&#x27;s current length and allocated length.<p>This isn&#x27;t a particularly hard problem. C just took a shitty shortcut to fake strings using byte arrays and the world glombed onto it. Now we&#x27;re stuck with a crappy &quot;standard&quot; that people should have scoffed at when it first showed its ugly face.
评论 #30037387 未加载
评论 #30037831 未加载
评论 #30039229 未加载
评论 #30037184 未加载
评论 #30040463 未加载
ErikCorryover 3 years ago
In practice it&#x27;s _worse_ than that because you probably don&#x27;t want a &quot;long&quot;, you probably want a particular size like a 64 bit integer. So you have to add ifdefs to call either strtol or strtoll depending on the size of &quot;long&quot; and &quot;long long&quot;.<p>And if you are using base 16 then strtol will allow an optional &quot;0x&quot; prefix. So if you didn&#x27;t want that you have to check for it manually.<p>Strtol also accepts leading whitespace so if you didn&#x27;t want that you have to test manually for it.<p>Don&#x27;t pass a zero base thinking it means base ten. This works almost all the time but misinterprets a leading zero to mean octal.<p>Good luck!
评论 #30036888 未加载
评论 #30036173 未加载
WalterBrightover 3 years ago
The #1 problem with C is buffer overflows. The solution is pretty simple:<p><a href="https:&#x2F;&#x2F;www.digitalmars.com&#x2F;articles&#x2F;C-biggest-mistake.html" rel="nofollow">https:&#x2F;&#x2F;www.digitalmars.com&#x2F;articles&#x2F;C-biggest-mistake.html</a><p>and does not break existing code.
评论 #30036936 未加载
评论 #30037276 未加载
评论 #30035090 未加载
评论 #30037281 未加载
评论 #30035044 未加载
评论 #30036675 未加载
评论 #30037279 未加载
评论 #30035869 未加载
评论 #30035075 未加载
dottedmagover 3 years ago
Seriously, the biggest gripe about C is the design of standard library?<p>Not the pervasive undefined behaviour and compilers that become more aggressive every release about breaking previously-working code?<p>Not the reams of code that assume sizes of integers and signedness of char?<p>Not the wild build process that makes it awfully hard to actually build anything that has any dependencies whatsoever.<p>strtol. Damn, what a nuisance!
评论 #30036123 未加载
评论 #30034668 未加载
评论 #30036058 未加载
评论 #30041549 未加载
评论 #30035496 未加载
stnclsover 3 years ago
From the article:<p><pre><code> char *forty_two_bee = &quot;42b&quot;; char *end; errno = 0; &#x2F;&#x2F; remember errno? long i = strtol(forty_two_bee, &amp;end, 10); </code></pre> &gt; This will return 0<p>No, this will return 42. strtol() parses greedily until a character cannot be parsed, but then it returns the conversion of what it did parse.<p>I guess the fact the author got this wrong... kind of proves their point that strtol()&#x27;s API is not great?<p>On the other hand, while the article purports to criticize a language, it then proceeds to only cover its standard library. Sure, C&#x27;s stdlib is old-fashioned, but there are many things in C that are <i>much worse</i> than its standard library! (And I say that as someone who still likes the language.)
dcposchover 3 years ago
Author mentions four increasingly obscure C replacements (first I&#x27;ve heard of Odin) without mentioning that the creators of the original C and Unix went on to make Go.<p>Go does not have manual memory management. Despite (actually because of) that captures the spirit and design goal of the original C beautifully. It&#x27;s a minimalist systems programming language.<p>One of the amazing things about Go is the standard library-- the thing he complains about with C. The Go standard library is incredibly readable. It&#x27;s night and day from C&#x2F;C++ where opening glibc&#x2F;STL etc is assault on the senses.
评论 #30041546 未加载
skywhopperover 3 years ago
What a weird post. The examples from Rust and Zig don’t fail gracefully, so they can’t be considered complete. Panicking on bad user input is bad code, too. And the main complaint seems to be that the C stdlib could be improved. But where it has been improved, the author complains that it’s really just doing the ugly stuff under the hood. What does the author think the Rust stdlib function is doing exactly?
tragomaskhalosover 3 years ago
Either I&#x27;m going mad - in which case please set me straight - or the Rust example doesn&#x27;t even compile: had to remove the odd-looking borrows on the method calls, and replace the type annotation in the final &#x27;if let&#x27; with a turbofish on the call.
评论 #30037285 未加载
gumbyover 3 years ago
&gt; It exists because it became part of the POSIX standard way back when a pdp7 was an advanced computer…<p>The PDP-7 was long obsolete by the time the POSIX effort started. By then the most common Unix host was a VAX (32 bits), though it, or Unix-alikes, ran on a variety of 16 and 32 bit machines, hence a desire for standardization.
creativemonkeysover 3 years ago
One of C&#x27;s design principles is to be fast at the cost of safety, just like an F1 formula car. It will let you make fast mistakes.<p>You drove a Corolla in college, then got a job and drove a cool BMW for several years and now you think you&#x27;re hot shit, so you hope in an F1 car and not only does it take forever to learn how to drive it, it has to be driven on a special track and the gearbox is different, what a nuisance!<p>&quot;If only we could add 4 doors, automatic transmission, snow tires, and a trunk to put our stuff in, people won&#x27;t keep getting into accidents with this car&quot;, you say. Right, but then it becomes a BMW. If you want real speed, you need to first go slow and master the car because otherwise you&#x27;ll crash and burn.<p>C is messy because real world hardware is very messy. You can&#x27;t push bytes through the hardware at its speed limit without getting your hands dirty, and we all come out into the real world wearing &quot;class Dog extends Animal&quot; white gloves.<p>To use C effectively, you should not be coding in C in your mind. You should be thinking in assembly, but your fingers should be typing C code. It&#x27;s not safe, but if you want to reach 230MPH and accelerate at 60MPH in 2.6 seconds, you better know exactly what you&#x27;re doing when you hop behind the wheel of that car. It&#x27;s not for the weak.
评论 #30036229 未加载
评论 #30035662 未加载
评论 #30037694 未加载
评论 #30036121 未加载
评论 #30040507 未加载
评论 #30036145 未加载
评论 #30039502 未加载
评论 #30038937 未加载
评论 #30052966 未加载
评论 #30039893 未加载
alkonautover 3 years ago
Wait is this article saying that there is no good&#x2F;obvious&#x2F;standard function to parse a string to a number and has the <i>two</i> obvious outputs of such a function (the number, and a bool or error code)?<p>Even a person in the 60s would realize that that’s the api for conversion from a string to a number (or any conversion that might fail)! What happened? Why do these functions even exist?
kazinatorover 3 years ago
This isn&#x27;t the usual way this is coded:<p><pre><code> char *one = &quot;one&quot;; char *end; errno = 0; &#x2F;&#x2F; remember errno? long i = strtol(one, &amp;end, 10); if (errno != 0) { perror(&quot;Error parsing integer from string: &quot;); } else if (i == 0 &amp;&amp; end == one) { fprintf(stderr, &quot;Error: invalid input: %s\n&quot;, one); } else if (i == 0 &amp;&amp; *end != &#x27;\0&#x27;) { f__kMeGently(with_a_chainsaw); } </code></pre> It&#x27;s actually like this:<p><pre><code> errno = 0; long i = strtol(input, &amp;end, 10); if (end == input) { &#x2F;&#x2F; no digits were found } else if (*end != 0 &amp;&amp; no_ignore_trailing_junk) { &#x2F;&#x2F; unwanted trailing junk } else if ((i == LONG_MIN || i == LONG_MAX)) &amp;&amp; errno != 0) { &#x2F;&#x2F; overflow case } else { &#x2F;&#x2F; good! } </code></pre> errno only needs to be checked in the LONG_MIN or LONG_MAX case. These cares are ambiguous: LONG_MIN and LONG_MAX are valid values of type long, and they are used for reporting an underflow or overflow. Therefore errno is reset to zero first. Otherwise what if errno contains a nonzero value, and LONG_MAX happens to be a valid, non-overflowing value out of the function?<p>Anyway, you cannot get away from handling these cases no matter how you implement integer scanning; they are inherent to the problem.<p>It&#x27;s not strtol&#x27;s fault that the string could be empty, or that it could have a valid number followed by junk.<p>Overflows stem from the use of a fixed-width integer. But even if you use bignums, and parse them from a stream (e.g. network), you may need to set a cutoff: what if a malicious user feeds you an endless stream of digits?<p>The bit with errno is a bit silly; given that the function&#x27;s has enough parameters that it could have been dispensed with. We could write a function which is invoked exactly like strtoul, but which, in the overflow case, sets the *end pointer to NULL:<p><pre><code> &#x2F;&#x2F; no assignment to errno before strtol int i = my_strtoul(input, &amp;end, 10); if (end == 0) { &#x2F;&#x2F; underflow or overflow, indicated by LONG_MIN or LONG_MAX value } else if (end == input) { &#x2F;&#x2F; no digits were found } else if (*end != 0 &amp;&amp; no_ignore_trailing_junk) { &#x2F;&#x2F; unwanted trailing junk, but i is good } else { &#x2F;&#x2F; no trailing junk, value in i } </code></pre> errno is a pig; under multiple threads, it has to access a thread local value. E.g<p><pre><code> #define errno (*__thread_specific_errno_location()) </code></pre> The designer of strtoul didn&#x27;t do this likely because of the overriding requirement that the <i>end</i> pointer is advanced past whatever the function was able to recognize as a number, no matter what. This is lets the programmer write a tokenizer which can diagnose the overflow error, and then keep going with the next token.
评论 #30034712 未加载
评论 #30034737 未加载
PaulDavisThe1stover 3 years ago
strto*() is the wrong API to use if you care about errors.<p><pre><code> char* forty_two = 42; int i; if (sscanf (forty_two, &quot;%d&quot;, &amp;i) != 1) { &#x2F;* error *&#x2F; } </code></pre> Sometimes, there&#x27;s more than one way to skin a cat, and one of them is more suited to the task at hand.
评论 #30041163 未加载
AtlasBarfedover 3 years ago
I thought Zig didn&#x27;t have unicode strings?<p><a href="https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;Zig&#x2F;comments&#x2F;9q3or3&#x2F;how_to_deal_with_strings_in_zig&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;Zig&#x2F;comments&#x2F;9q3or3&#x2F;how_to_deal_wit...</a><p>If that&#x27;s true, Zig is NOT a modern language. Modern languages use international strings, and are unicode aware with a good unicode aware string library.<p>For crap&#x27;s sake, the code example for comparing modern languages USES A STRING. The fact it is not unicode doesn&#x27;t matter.
评论 #30054901 未加载
EVa5I7bHFq9mnYKover 3 years ago
That case has existed for 40 years now, yet C still stands. Guess its the power of network effect.
futharkshillover 3 years ago
If a user wants to parse integers etc. from a string, the function snprintf and family is often applied. It is a neatly simple function. This article seems to invent a problem rather than an organic one.
评论 #30035603 未加载
treeshateorcsover 3 years ago
the rss feed is broken on that site, it outputs relative links (as opposed to absolute links)
gengiskushover 3 years ago
How about leaving the old stuff you want to &quot;replace&quot; alone? People are using it.