[HN Gopher] Considering C99 for Curl
___________________________________________________________________
Considering C99 for Curl
Author : mariuz
Score : 187 points
Date : 2022-11-22 10:05 UTC (12 hours ago)
(HTM) web link (daniel.haxx.se)
(TXT) w3m dump (daniel.haxx.se)
| gweinberg wrote:
| Won't older versions of curl source code be available forever in
| any case? I understand that people use very old machines/code
| sometimes, but I don't think it's that unreasonable to say "if
| you must use a compiler with capabilities stuck in the 20th
| century, you can't use curl source newer than late 2022".
| andy128k wrote:
| That's how software stagnates and dies.
|
| > ... risk opening the flood gates for people rewriting things...
|
| This sounds like "we feel that changes are needed but we will not
| be able control it".
| kazinator wrote:
| In C99 there are some nice things over C89 that aren't new
| syntax, like initializing aggregates in automatic storage
| ("stack") with non-constant expressions: struct
| point p = { getx(obj), gety(obj) }; /* C90 error, C99 OK */
|
| GCC had this as an extension before C99. Coding around that one
| can get ugly, and it's just a syntactic limitation.
|
| Also, the C99 preprocessor is more powerful, with variadic
| support.
|
| The macros I implemented in the cppawk project (awk with C
| preprocessor) would be impossible without C99. I was able to make
| a multi-clause loop macro, with user-definable clauses.
|
| https://www.kylheku.com/cgit/cppawk/about/
| impoppy wrote:
| I don't really get why Daniel decided not to go with C99. Doesn't
| C99 compiler produce the same machine code for ANSI C source
| code? They could start writing new code in a newer standard and
| fixing old code in a newer standard gradually, so most of `curl`
| and `libcurl` source code would have slowly, but steadily
| transitioned to a newer standard. Or am I missing something?
| Karellen wrote:
| > Doesn't C99 compiler produce the same machine code for ANSI C
| source code?
|
| Only if a C99 compiler is available. As the post points out:
|
| > The slowest of the "big compilers" to adopt C99 was the
| Microsoft Visual C++ compiler, which did not adopt it properly
| until 2015 and added more compliance in 2019. _A large number
| of our users /developers are still stuck on older MSVC versions
| so not even all users of this compiler suite can build C99
| programs even today, in late 2022._
|
| (emphasis mine)
| 0xcde4c3db wrote:
| And that's just the "big compilers" supporting the "big
| platforms". If you're shipping some bespoke embedded platform
| where the toolchain/OS integration was custom work, you might
| very well _never_ upgrade the compiler and just pick a new
| one when you 're forced to define a new platform due to the
| hardware going EOL.
| leeter wrote:
| I'm mixed on this personally, on one hand... I get it.
| Having curl on the XYZ micro controller you're using for a
| project is good. At the same time the only reason MSVC
| added c99 support was community pressure because major
| projects said "we don't care about MSVC anymore we're
| moving on"[1]. So clearly there is a correlation between
| vendors and versions. If the vendors don't feel pressure to
| support newer versions then they'll just continue to ship
| the garbage they've been shipping for years. I personally
| don't have a good answer for this. Daniel very clearly has
| made his decision and I'll respect that as it's not my
| project.
|
| [1] Also because the C++ committee ignored Herb and just
| forced it into later C++ revs from a library perspective.
| TylerE wrote:
| How hard would it be to do something like C99 (or
| whatever) > LLVM IR > C89 (auto-generated, doesn't have
| to be human readable) > niche compiler?
| pjmlp wrote:
| There is no reason to support C99, when C11 and C17 are
| supported.
|
| Naturally without the stuff that got made optional in C11, no
| need to spend development effort on legacy features.
| quelsolaar wrote:
| More language isnt necceseraly better. The more features a
| language has the harder it becomes to read. When a language
| gives you a lot of options, you do spend more time chosing
| btween options that on the problem at hand.
| impoppy wrote:
| I think I can see why, I never tried C or C++, but Zig was a
| pleasure to learn and play around with.
| pizza234 wrote:
| Smaller language isn't necessarily better, either. Case in
| point: no booleans make a language "smaller"; result: each
| codebase will have their own, different, implementation.
| quelsolaar wrote:
| There is no one way to do booleans because the choice of
| implementation depends on what your goals are. If you value
| space you should pack you booleans as bits in a larger
| type, but if you want fast access you should use int. bool
| has some nice properties becaus it doesnt have multiple
| states of true unlike int. C gives you types that have
| properties but doesnt prescribe what they should be used
| for.
| pizza234 wrote:
| Packed boolean arrays are an entirely different thing; as
| a matter of fact they are _arrays_ , not a primitive data
| type.
|
| The boolean primitive data type is a standard in modern
| languages. Take any language: Rust, Go, Zig... and C99
| (kind of).
|
| In C89, a project may use enums. Another macros. Another
| ints.
| jmull wrote:
| The nuance from the article is that they _are_ adopting C99,
| but incrementally, feature by feature, as needed.
| pizza234 wrote:
| He addresses this point in the article:
|
| > [...] we would have to go gently and open up for allowing new
| C99 features slowly
|
| > A challenge with that approach, is that it is hard to verify
| which features that are allowed vs used as existing tooling
| normally don't have that resolution.
|
| > The question has also been asked that if we consider bumping
| the requirement, should we then not bump it to C11 at once
| instead of staying at C99?
|
| The motivation ultimately boils down to:
|
| > Ultimately, not a single person has yet been able to clearly
| articulate what benefits such a C flavor requirement bump would
| provide for the curl project
| sanxiyn wrote:
| I mean, I am not a curl developer so I don't get to vote, but
| restricting variable scopes to loops alone sounds worthwhile
| to me.
| jmull wrote:
| You can still add a set of curly braces around the loop to
| scope variables.
|
| The syntax isn't as nice, and you have to remember to do it
| (maybe a linter can help with that) but it ends up more of
| a "nice to have".
| warbler73 wrote:
| > tldr: we stick to C89 for now.
|
| Cool.
| quelsolaar wrote:
| I think this is entierly the right approach. With smaller
| language footprint you have easier the code is to read and you
| will have less issues running the code on a wide variety of
| platforms. Many c99 features (like Variable Length Arrays) have
| been proven to be less than well designed and since been made
| optional.
| sanxiyn wrote:
| Yes, VLA is bad, but declare anywhere is very desirable. curl
| can't move due to old MSVC, but once that is solved, it would
| make a lot of sense to move to C99. The post itself says "It is
| not a no to C99 forever".
| mananaysiempre wrote:
| Caveat re VLAs: while C23 doesn't return VLAs to mandatory
| status, it does require variably modified types; so no stack
| space footgun but still a significant complication in the type
| system: void foo(size_t n) { int a[n][n]; }
|
| does not have to be supported outside C99 but
| void bar(size_t n, void *p) { int (*pa)[n][n] = p; }
|
| has to be in both C99 and C23 (though not in C11 or C17).
| warinukraine wrote:
| > Ultimately, not a single person has yet been able to clearly
| articulate what benefits such a C flavor requirement bump would
| provide for the curl project. We mostly see a risk that we all
| get caught in rather irrelevant discussions and changes that
| perhaps will not actually bring the project forward very much.
| Neither in features nor in quality/security.
| krylon wrote:
| In 2007-2009, I worked a job that for most was consisted of
| maintaining a C89 codebase. We were using OpenWatcom, which at
| the time did not have complete C99 support.
|
| But in retrospect I'm surprised to see how many features we used
| liberally would have been unavailable in pure C89. snprintf first
| and foremost. But also // comments, __func__, and stdint.h
| badsectoracula wrote:
| AFAIK almost all of C99 functionality was basically about
| standardizing features found in existing compilers prior to it.
| Karellen wrote:
| The tipping point for me would be `snprintf()` and related
| functions. I've found it generally more useful/memorable/readable
| than strncpy()/strlcpy() and other updates to the dangerous and
| deprecated strcpy() just for copying strings safely, never mind
| it's other formatting abilities.
|
| If Curl already has its own "decent and functional replacement"
| for `snprintf()` that's used extensively throughout the codebase,
| or if they just don't need that functionality (I haven't checked)
| then I guess that's not an issue. But that would be the big
| selling point as far as I'm concerned.
| unwind wrote:
| If anyone reading this and feels uncertain on how this is done,
| _DON 'T_ do this: snprintf(dest, sizeof dest,
| source); // BAD code do not repeat
|
| that looks great at first sight, just another size-checked way
| of copying strings, but remember that the third argument to
| `snprintf()` [1] is of course a `printf()`-style formatting
| string. So if that `source` argument contains any percent
| symbols, there's gonna be a party in your computer and both
| Undefined and Behavior are going to show up. You don't want
| that.
|
| Instead, if you want to use `snprintf()` for this, remember to
| do: snprintf(dest, sizeof dest, "%s",
| source);
|
| [1]: https://linux.die.net/man/3/snprintf
| Karellen wrote:
| Thanks for mentioning this. I didn't include it in my comment
| because I originally thought it was too obvious, but
| considering it now, it probably was worth making explicit.
| unwind wrote:
| I blame Stack Overflow for conditioning me into seeing more
| of the possible ways things could break, when it comes to C
| code. :)
| kazinator wrote:
| But snprintf can be used in C90. You just detect if it's
| available and use it, as if it were any other platform-specific
| function.
| dheera wrote:
| > The tipping point for me would be `snprintf()` and related
| functions
|
| Functions can always be implemented with additional header
| files.
|
| They aren't actual extensions to the language.
| masklinn wrote:
| > But that would be the big selling point as far as I'm
| concerned.
|
| I mean, it's a trivially replicated function, you can just copy
| it over from an existing codebase. So it's not exactly a major
| feature.
| tialaramex wrote:
| Note that strncpy() is _not_ intended for safety. The purpose
| of strncpy() is to write to fixed size data structures such as
| part of the filesystem where you don 't want to store NUL
| termination on strings.
|
| Like 1980s Internet protocol features the rationale for weird
| things in C is more often "That's how Unix works" than "This is
| actually a clever safety feature".
| synergy20 wrote:
| then why not just use memmove() instead of strncpy() if no-
| NUL is the goal? not to mention memmove() is overlap-safe.
| masklinn wrote:
| > then why not just use memmove() instead of strncpy() if
| no-NUL is the goal?
|
| no-nul is not the _goal_ of strncpy, it 's the _effect_ of
| strncpy.
|
| strncpy is designed to work on _fixed-size, nul-padded_
| strings. That 's why it _fills the destination buffer with
| nuls_ if the source is too short, and it doesn 't guarantee
| nul-termination (if the source is exactly the size of the
| destination).
| kazinator wrote:
| > _write to fixed size data structures such as part of the
| filesystem where you don 't want to store NUL termination on
| strings_
|
| ... AND where you want to pad the remaining space with zero
| bytes, so that you don't leak uninitialized memory onto the
| disk, or network.
|
| The null byte padding behavior of strncpy makes it clear what
| the intended use was.
|
| Also, the way C initializes character arrays from literals
| has strncpy-like behavior, because the entire aggregate is
| initialized, so the extra bytes are all zero:
| char a[4] = "a"; // like strncpy(a, "a", 4); char
| b[4] = "abcd"; // like strncpy(a, "abcd", 4);
|
| the compiler could literally emit strncpy calls to do these
| initializations, so we might say that strncpy is a primitive
| that is directly relevant for run-time support for a C
| declaration feature.
| anthk wrote:
| Get strlcpy and strlcat from OpenBSD.
| pjmlp wrote:
| Any version that still relies on separate parameters is
| unsafe, no matter what.
|
| Some typo on the buffer limits and the same hazards as
| always.
|
| Only fix is hardware memory tagging.
| anthk wrote:
| Multics?
| kzrdude wrote:
| Do we have a source for what the intended purpose is? I think
| you speak well to the effective purpose, but I'm not sure if
| it was that clear when it was introduced.
| lemmiwinks wrote:
| https://devblogs.microsoft.com/oldnewthing/20050107-00/?p=3
| 6...
| kzrdude wrote:
| Doesn't say anything about the intention as understood
| when it was introduced
| masklinn wrote:
| > I think you speak well to the effective purpose, but I'm
| not sure if it was that clear when it was introduced.
|
| It was completely clear, and can easily be inferred from
| its specified behaviour.
|
| It's just completely useless nowadays, because its purpose
| is essentially obsolete, because the data type it works
| with is almost never used anymore.
|
| strncpy works with fixed-size nul-padded fields as you'd
| find in e.g. mainframe-type software. That is why it:
|
| - fills the destination buffer with NULs if the source is
| shorter
|
| - does not nul-terminate if the source is the same size or
| longer than the destination
|
| strncpy is essentially equivalent to zero-ing a buffer of
| size `n` then copying the first `n` bytes of src (up to the
| first nul) in the target
| kzrdude wrote:
| That's your understanding now. Fine, but not evidence of
| what someone else thought about this some decades ago.
|
| (I don't use strncpy and don't defend its functionality,
| just want to know what was intended when it was
| introduced.)
| kzrdude wrote:
| I found an actual quote of a source which verifies the
| intention for fixed-length fields:
| https://softwareengineering.stackexchange.com/a/438090
| spc476 wrote:
| On early Unix systems, the directory structure was a
| simple 16-byte record; 14 bytes for the name, and 2 bytes
| for the inode. [1] strncpy() was used to simply record
| the file name into this structure.
|
| [1] "UNIX Implementation" by Ken Thompson, _The Bell
| System Technical Journal_, July-August 1978, Vol 57, No
| 6, Part 2, pg 1942.
| tjoff wrote:
| Many protocols still relevant today make use of that
| structure, it still has widespread use.
| masklinn wrote:
| For the average _protocol_ you 're going to init the
| entire message then set into it, you don't need to fully
| zero fields.
|
| This is mostly relevant to write into existing memory or
| memory-mapped records.
| tjoff wrote:
| Sometimes yes, but you must also not null-terminate the
| strings in those cases.
|
| And on embedded devices you are often memory constrained
| so you might reuse an existing structure.
| dizzant wrote:
| Is the original intent of strncpy() germane to the GPs
| comment? Explicitly stating the max length to copy is an
| effective tool for avoiding buffer overruns, regardless of
| whether the designers imagined that important use case.
| masklinn wrote:
| Except strncpy is broken for C strings, because it doesn't
| guarantee nul termination. So if you forget to force a
| termination on every use, you get buffer overruns.
|
| Not only that, but (because of its actual purpose) it also
| fills the buffer with nuls, which is a complete waste of
| resources.
|
| So yes, the original intent of strncpy() germane to the GPs
| comment, because it makes strncpy actively dangerous and
| complete shit when working with C strings.
| tialaramex wrote:
| But the thing it does (fill out a fixed sized buffer
| without caring about NUL-termination) is not at all what
| you'd want from a safety feature.
|
| If you look at this function assuming it's a safety
| feature, that's a huge surprise, and indeed if you were
| skimming you might miss what it does because (in the
| context of "it's a safety feature") this is an insane
| choice. "Why would you do that?". Well, because it's not a
| safety feature.
|
| The perf cost isn't what you'd expect from a safety feature
| either. Suppose we have a 1MB buffer, and we strncpy "THIS"
| into it using n = 1024. That's just four bytes right? Nope.
| strncpy() will write "THIS" and then 1020 zero bytes.
| torstenvl wrote:
| The issue is that strncpy() isn't a str___() function,
| despite its name. It's a 0x00-padded memcpy.
| masklinn wrote:
| But it's not an str* function, it's an strn* function.
| And most (though not all, that would be too easy) work on
| fixed-size (hence the n) nul-padded strings.
| torstenvl wrote:
| No, it isn't a string function of any kind. "A string is
| a contiguous sequence of characters terminated by and
| including the first null character." SS 7.1.1.
|
| Calling a bespoke byte-sequence data structure a "string"
| is inaccurate. Treating strncpy() as a string function is
| erroneous and can easily lead to memory corruption.
| masklinn wrote:
| torstenvl wrote:
| > _Have you considered giving reading comprehension a
| try?_
|
| Don't do this.
| masklinn wrote:
| Then don't demand it by wilfully misunderstanding
| comments in order to "well actually" them.
| cesarb wrote:
| The _output_ side of strncpy() might not be a str___()
| function, but AFAICS the _input_ side of strncpy() is
| clearly a str___() function, since it stops reading (but
| not writing) at the first NUL byte.
| [deleted]
| attractivechaos wrote:
| The printf() family is much slower than direct string
| operations. snprintf() is not a good substitution when string
| copying is frequent.
| camel-cdr wrote:
| I tend to stay away from the entire C style strings approach in
| general whenever I write C.
| cassepipe wrote:
| I _always_ use antirez 's SDS string Library. The fact that
| they are compatible C strings with the only price to pay
| being a call to sdsfree() instead of free I like a lot.
| Simple and yet super useful. Check it out.
| anthk wrote:
| Strlcpy and strlcat from OpenBSD works.
| pjmlp wrote:
| Only for those that never do mistakes with parameter
| passing.
| camel-cdr wrote:
| IMO you should store the size of your strings. If you know
| the sizes already then you can just memcpy/memmove.
| tssva wrote:
| Curl uses its own implementations, curl_msnprintf and
| curl_mvsnprintf.
| lsllc wrote:
| Previously posted by /u/edent (not much discussion though):
|
| https://news.ycombinator.com/item?id=33636732
| tinglymintyfrsh wrote:
| Is there any user value to changing? Probably not.
|
| Is there risk associated with changing? Probably yes in terms of
| security and limiting compatibility.
|
| It probably doesn't make sense to change now unless there are
| specific reason(s) that will lead to impactful improvements.
| cesaref wrote:
| The reasons given are reasons to stick with C89 forever. Change
| has risk, and there are advantages and disadvantages. If there
| were no advantages gained from C99, it wouldn't exist (people
| don't release language updates for no reason).
|
| A much more interesting question is if you were writing curl
| today, what would you do. If the answer is still 'C89' then we as
| a profession have to wonder why - did we get it exactly right,
| and there are no lessons from the last 30 years, or is the fact
| there are no better alternatives deeply depressing.
| BiteCode_dev wrote:
| The question is more complicated than that: curl is so popular
| it is used on systems where c99 is not available. The question
| is how many of those exist, and are at which point it's not
| worth supporting them anymore.
| UncleOxidant wrote:
| > curl is so popular it is used on systems where c99 is not
| available.
|
| What systems don't support a version gcc that compiles c99 at
| this point?
| BiteCode_dev wrote:
| Old systems in ports and airports, military systems,
| anything that has a 50 years shelve life...
| UncleOxidant wrote:
| How many old systems like that are connected to the
| internet and could actually use curl?
| BiteCode_dev wrote:
| More than you would think, but curl is used to talk to
| the local network too, or inside VPN as well.
|
| Some hacks are quite crazy.
|
| E.G: there is this very old navy broacasting protocol,
| NMEA (https://en.wikipedia.org/wiki/NMEA_0183), that was
| designed so it could be transmitted through old fashion
| radio waves. You'll find it in some sonars, water sensors
| or AIS beacons. For this reason, despite that it looks
| more like a layer 4 protocol, it embeds its own packet
| format and checksum, all in ASCII, that clients are
| expected to parse.
|
| Now of course, a lot of devices are still emitting their
| data in NMEA, and it's not uncommon to be able to just
| telnet or netcat (if UDP) into one to see the data
| flowing.
|
| But after a while, people started to aggregate those data
| from their numerous sources into one single router, and
| expose this router for convenience through... HTTP over
| TCP/IP.
|
| And now you have those all those old computer towers
| (some still rocking a CRT screens or windows xp) doing
| long polling to get broadcasting data over a protocol
| that was made for request/reponse, to read the payload
| that is another protocol that was meant for radio
| equipment and hence requires manual consistency checks,
| that is transported by yet another protocol that is doing
| its best to preserve packets.
|
| And they say the spirit of hacking is dead :)
|
| (sometimes I feel IoT or domotic stacks look the same
| honestly)
|
| Of course, somewhere in there, there is a curl call. The
| question is therefore does curl author want to support a
| potential upgrade path for such twisted use case or not.
| I would say "nahhhh", but maybe curl had precisely the
| success it did because the author was ready to support it
| in crazy settings.
| nibbleshifter wrote:
| Quite many!
| [deleted]
| bhawks wrote:
| Just a terminology rant: it is used in -builds- where c99 is
| not available.
|
| Particularly the MSVC ecosystem is identified in TFA as being
| a late adopter.
|
| Once built c99 code can run where it wants.
| Karellen wrote:
| > Once built c99 code can run where it wants.
|
| Is that true on the MSVC ecosystem?
|
| Don't you have to compile separately for each `msvcrt`
| environment, as I thought they aren't binary compatible?
| And would a non-C99 msvcrt necessarily have an `snprintf()`
| implementation in its libc-equivalent dll?
| cesarb wrote:
| You can call code compiled with one msvcrXX from code
| compiled with a different msvcrXX, provided that you
| don't try passing things from one to the other (that is,
| no passing a pointer to a FILE structure, or even a file
| descriptor since the file descriptor table is on the
| msvcrXX instead of the kernel), and always free or
| realocate memory using the same msvcrXX (that is, don't
| allocate memory and expect your caller to call free() on
| it, always provide a custom deallocation function for
| your objects).
|
| This is possible because, unlike on Linux where function
| names are global, on Windows function names are scoped to
| the DLL, so you can have MSVCR71.DLL and MSVCR81.DLL
| loaded at the same time in the same process and they
| won't interfere with each other.
| Karellen wrote:
| OK, but isn't the point of building a program that links
| to (say) MSVCR71.DLL that you're expecting to run it in
| an environment where (say) MSVCR81.DLL isn't available?
|
| I don't see how that fixes the problem of possibly not
| having an snprintf() implementation on a system that
| doesn't have a C99-compatible MSVC runtime environment.
|
| Did I miss an implication of your comment somehow?
| Arnavion wrote:
| If you compile your program against some MSVCRT then it's
| your job to make sure that MSVCRT is available on the
| machine where your program is installed, by delegating to
| its installer.
|
| All supported MSVCRTs are installable on all supported
| Windows SKUs.
| TylerE wrote:
| Supported is really doing a lot of heavy lifting there,
| isn't it?
|
| Windows 7 and 8 haven't been supported in years, but are
| still pretty common in the wild.
| __alexs wrote:
| > This is possible because, unlike on Linux where
| function names are global, on Windows function names are
| scoped to the DLL
|
| This is also possible on Linux with linker scripts AFAIK.
| rkeene2 wrote:
| Hmm, not really in the same way -- to do this with linker
| scripts you would need to rename some of the symbols in
| the library being consumed.
|
| What you can use, to a limited extent, is dlmopen().
|
| Shared objects in Linux are just really late linked
| static objects, with fix-ups (hence PIC requirements).
|
| In macOS and Windows, there are heirarchies.
| coldpie wrote:
| For systems programming, C89 is definitely a "sweet spot". It's
| relatively easy to write a compiler for and was dominant when
| system variety was at its highest, so it is best supported
| across the widest variety of platforms. Later C standards are
| harder to write compilers for and have questionable features
| like VLAs and more complicated macro syntax. C++ is a hideous
| mess. Rust is promising, and would probably be my choice
| personally, but it's also still fairly new and will limit your
| deployment platform options.
|
| C89 is still a reasonable choice today. I don't think it's
| depressing. It's a good language, and hitting the sweet spot of
| both language design and implementation is _really hard_ , so
| you'd expect to have very few options.
| kibwen wrote:
| Re: Rust, Curl is modular enough that you don't need to
| rewrite it in Rust in order to enjoy some of its benefits,
| you can just tell Curl to use Hyper (Rust's de-facto HTTP
| lib) as a backend. For the past few years they've been
| working on getting the Hyper backend to pass the Curl test
| suite and they're down to five remaining tests, so perfect
| support looks to be imminent:
| https://github.com/orgs/hyperium/projects/2/views/1
| (seanmonstar occasionally streams on Twitch if you'd like to
| watch him work on these).
| bitexploder wrote:
| Also, and this sort of blows my mind, but Rust is almost 10
| years old. It is a pretty darn stable language, especially
| for greenfield projects like a new HTTP library. The better
| Rust gets at interop the more it will begin to eat the
| systems programming world IMO, and we all benefit, even if
| it is quietly doing it without much fanfare.
| laumars wrote:
| I was with you right up until "quietly doing it without
| much fanfare".
|
| Personal opinions of Rust aside, it has gained so much
| fanfare that "rewrite it Rust" is now practically a meme.
| b3morales wrote:
| Rust is over 12 years old at this point as a publicly-
| available project (its development started internally
| sometime in the late 00s; it was publicized in summer of
| 2010).
| steveklabnik wrote:
| Periodization is hard, especially with Rust, but if we're
| talking about reliability, counting time before 1.0 in
| 2015 doesn't feel right to me. Seven and a half years is
| still a long time :)
| b3morales wrote:
| Agree, time since v1.0 is a very reasonable measure.
| conaclos wrote:
| 10 years and still an okish IDE experience... This is
| going to stay with Rust. The problem is not the tooling,
| but the language.
| throwaway0x7E6 wrote:
| some things actually just work
| chrisseaton wrote:
| > If there were no advantages gained from C99, it wouldn't
| exist (people don't release language updates for no reason).
|
| Why isn't it possible that the updates aren't as good as the
| people who wrote them thought they were?
| pjmlp wrote:
| VLA certainly were proven as a very bad idea, to the extent
| Google has paid the effort to remove all of it from the Linux
| kernel, as security measure.
| uecker wrote:
| As someone tangentially involved in this, I think this was
| misguided. But Linus also was not happy about code
| generation with VLAs.
| tpush wrote:
| > As someone tangentially involved in this, I think this
| was misguided.
|
| Do you mean the removal of VLAs from Linux? Why do you
| think that was misguided?
| sfpotter wrote:
| The requirements for writing curl are different from the
| requirements for writing other software. Just because C89 is a
| good choice for curl doesn't mean that C99 isn't a better
| choice for other things. The failure isn't in having revised a
| language, it's in thinking that all projects using the older
| version must upgrade. The idea that progress is linear is an
| illusion.
| sylware wrote:
| "people don't release language updates for no reason", indeed,
| many reasons are in the end "planned obsolescence" or ways to
| make even a naive compiler so much complex that only few
| remains, and of course in control of very few groups of ppl,
| and it is near impossible to implement reasonably a real life
| alternative.
|
| My opinion is C is already way too rich and complex. I would
| stick to c89 with benign bits of c99 and c11. The benchmark
| being "one average system developer coding a naive and real
| life C compiler in a reasonable amount of time and effort".
|
| That said, I know that my "next" C compiler will probably be a
| RISC-V assembler with a very conservative usage of a macro
| preprocessor.
| tragomaskhalos wrote:
| > Other languages
|
| > We do not consider switching or rewriting curl into any other
| language.
|
| Rustaceans at the back of the auditorium slowly lower their hands
| ...
| nine_k wrote:
| That would be a major effort, without a very clear benefit.
| Curl is massive, just scroll through its man page.
| sgt wrote:
| I just scrolled through the man page at a speed of 15 pages
| per second. Aside from that, curl is an extremely important
| and impressive piece of software that I use daily.
| forgotpwd16 wrote:
| >Rustaceans at the back of the auditorium slowly lower their
| hands ...
|
| And start a rewrite themselves afterwards.
| pornel wrote:
| The approaches C and Rust projects have to upgrades are so
| radically different, it's comical:
|
| curl: let's not rush, 23 years is not enough time for people to
| update their compilers.
|
| Rust: the compiler released last Thursday is the oldest
| supported version.
| fgeiger wrote:
| I'll just leave this here:
|
| https://daniel.haxx.se/blog/2022/02/01/curl-with-rust/
| jmull wrote:
| It's not really up to the curl people to rewrite it in rust.
|
| It's for the proponents of rust.
|
| Personally, I'm largely convinced that writing in rust will
| lead to safer implementations... now I'm just waiting for the
| full-featured, well-though-out, stable, useful rust
| implementations to appear.
|
| I'm not married to curl. Where's "rurl" or whatever? If it
| exists and does something useful as well as curl (or better),
| I'll happily use it.
| adql wrote:
| Well, curl is a bit of swiss army chainsaw for protocols and
| _in general_ there is rarely a need to have same subsystem
| (of "downloading/sending something to an url) have support
| for protocols from HTTP thru IMAP all the way to LDAP.
|
| So there is really no reason to use it Rust, use smaller,
| protocol-specific libs, less security problems and if you
| need multi-protocol support just switch by protocol and maybe
| write some wrappers.
|
| And for calling it from C, "Rewrite it in Rust but make ABI C
| compatible" means you have to repeat a lot of Curl's
| idiosynchracies all while recreating all of the
| functionality. Looking at https://curl.se/docs/security.html
| there isn't that many of them that Rust safety would prevent
| so the real gains from that aren't probably all that great.
|
| Now OpenSSL on another hand...
| [deleted]
| [deleted]
| Arnavion wrote:
| https://github.com/curl/curl/blob/master/docs/HYPER.md
| bsdz wrote:
| > I think there are still much better things to do and much more
| worthwhile efforts to spend our energy on that could actually
| improve the project and bring it forward.
|
| > Like improving the test suite, increasing test coverage, making
| sure more code is exercised by the fuzzers.
|
| I wonder if using a more recent version of C might draw in more
| developers willing to contribute (in a similar vein to Linux
| kernel introducing Rust).
| coldpie wrote:
| It seems unlikely. If you're capable of & interested in hacking
| on something like curl, having to put your variable
| declarations at the top of the block probably isn't going to be
| a deal-killer for you.
| josephcsible wrote:
| > However, there is no longer any modern compiler around that
| does not support this.
|
| What features of C99 isn't this true of today?
| cesarb wrote:
| > What features of C99 isn't this true of today?
|
| IIRC, MSVC stubbornly refuses to add support for variable-
| length arrays (which AFAIK are required for full C99 support).
| I don't know if there's anything else on that list of C99
| features that MSVC doesn't support yet.
| asveikau wrote:
| Interestingly, I've seen code that uses the flexible array
| member idiom with MSVC. I'm fairly certain I first saw this
| in the windows code base when I worked at MS, and I believe
| it may even be in some public headers somewhere. In order to
| compile on MSVC, the trick uses MemberName[0] or
| MemberName[1] rather than the standard MemberName[]. GCC and
| clang warn about this. I suspect it might have been a common
| idiom in pre-C99 days.
| Karliss wrote:
| You are probably confusing flexible array members with VLA.
| Those are two completely different features. You are
| thinking about the one where last member of struct is an
| array and you adjust size based on malloc size when
| allocating struct. VLA feature allows you specifying
| arbitrary non constant expression when declaring local
| stack variables with array type. Something like:
|
| // VLA
|
| int foo(int n) { int array[n]; }
|
| // flexible array member
|
| struct s { int n; double d[]; }; struct s _s1 =
| malloc(sizeof (struct s) + (sizeof (double)_ 8));
| asveikau wrote:
| I'm not confusing them. That's why I said flexible array
| member and not VLA.
|
| I don't need a lecture. I have actually lectured on C
| before.
|
| I do have them bucketed similarly in my mind. They are
| both c99 features about variable sized arrays. MS has not
| implemented either one iirc.
| xeeeeeeeeeeenu wrote:
| >MS has not implemented either one iirc.
|
| Flexible array members were implemented a long time ago.
| The oldest Visual C++ I have at hand is 2005 and it
| already has them (although only in C mode).
| xeeeeeeeeeeenu wrote:
| >MSVC stubbornly refuses to add support for variable-length
| arrays (which AFAIK are required for full C99 support).
|
| They were made optional in C11. It was a good decision
| because it's a dangerous misfeature.
| uecker wrote:
| I find them very useful and they often make the code
| cleaner. A dynamic run-time bound for a buffer can also
| make the code safer. VLAs are only dangerous when
| implemented naively (allocated on the stack without stack
| probing).
| xeeeeeeeeeeenu wrote:
| >are only dangerous when implemented naively (allocated
| on the stack without stack probing).
|
| That's how it's implemented in all the major compilers.
| Anyway, even a hypothetical heap-based implementation
| would be bad because there's no way to report allocation
| errors.
| uecker wrote:
| GCC has stack probing.
| lelanthran wrote:
| > IIRC, MSVC stubbornly refuses to add support for variable-
| length arrays (which AFAIK are required for full C99
| support).
|
| You are correct that VLAs are mandatory for C99, but they
| turned out to be such a bad idea that they are optional in
| C11 onwards.
|
| > I don't know if there's anything else on that list of C99
| features that MSVC doesn't support yet.
|
| IIRC, MSVC's `snprintf` and friends are broken (returns
| incorrect values and/or interprets the size parameter
| incorrectly). I think all of the annexure K stuff is broken
| in MSVC.
| masklinn wrote:
| > I think all of the annexure K stuff is broken in MSVC.
|
| Doesn't annex k only exist in MSVC because it's a bunch of
| crap MS got the committee to add and no one else wanted to
| implement?
|
| And isn't it a C11 thing?
| lelanthran wrote:
| > Doesn't annex k only exist in MSVC because it's a bunch
| of crap MS got the committee to add and no one else
| wanted to implement?
|
| Yes, but in a perverse twist of fate, Microsoft's
| implementation does not conform.
|
| > And isn't it a C11 thing?
|
| I stand corrected, it is a C11 thing.
| kevin_thibedeau wrote:
| The MS implementations were given different semantics in
| annex K. They aren't standard compliant.
| uecker wrote:
| I think VLAs were a very good idea and they were not made
| optional because somebody thought they were a bad idea, but
| simply to make C11 easier to implement. VLA can be
| dangerous when the size depends on external input an when
| implemented without stack probing.
| lelanthran wrote:
| > when implemented without stack probing.
|
| I dunno how to probe the stack in standard C, and so I
| never used VLAs, nor allowed them because (I thought
| that) there was no way to determine if a VLA declaration
| would cause a stack overflow.
| pjmlp wrote:
| No they are not.
|
| Google has paid the development effort for the Linux
| kernel to get rid of all VLA occurrences.
| cesarb wrote:
| The Linux kernel is a very different environment than
| user space; it has a very limited stack space (16 KiB
| IIRC), and the consequences of exceeding that are worse
| than in user space.
|
| > Google has paid the development effort for the Linux
| kernel to get rid of all VLA occurrences.
|
| IIRC, what they were really interested in getting rid of
| was not the normal VLA we're talking about, but something
| even more esoteric called VLAIS (variable length arrays
| in structures), which clang didn't support. See
| https://lwn.net/Articles/441018/ for a discussion about
| that.
| pjmlp wrote:
| I have seen all Linux Plumber talks on the subject.
| uecker wrote:
| I was tangentially involved in this and I think this was
| misguided.
| camel-cdr wrote:
| You don't even have to go to C99. Microsoft just had a
| confirming C89 preprocessor implementation for 3 years. [0]
|
| [0] https://learn.microsoft.com/en-
| us/cpp/preprocessor/preproces...
| attah_ wrote:
| Didn't Linux just switch for added safety against some
| speculative execution vulns? Keeping iterator variables scoped to
| their respective loops, it seems.
|
| Isn't cURL susceptible to this too? (Not to mention i always find
| that style much nicer :)
___________________________________________________________________
(page generated 2022-11-22 23:01 UTC)