8
kiki
3y

they say everything "old" is better, but in programming, dependencies in C was a mess. Shut up. Sometimes C is a cult enforced by those who don't even write in C. Now I build my projects with Parcel in less than a second with no configuration. It uses a full-blown AST for everything. If I want more performance with similar DX, I use fastpack, bringing build time down to tens of milliseconds.

art? charli xcx, sophie xeon, death grips, just to name a few. they made things that weren't imaginable before, ultimately pushing music forward. Hendrix is good but they're just incomparable in terms of beauty, complexity and sophistication.

literature? every old book I read feature same conflicts. they are so similar it's almost boring to read them. meanwhile, Erlend Loe delivers a complex idea without using a conflict (!) and without any character changes. that's insane.

"older is better" is getting old. it's time for you to seek for some other reusable gibberish to insult what other people create.

finally, let me remind you that you, my friend, create nothing.

Comments
  • 7
    C is a cult. What do you think "C" stands for?

    Now let me introduce you to our lord and savior: @Fast-Nop

    C++ is cult ++
  • 5
    C definetly has its uses, but there's a lot of things that I would overhaul in a modern language

    the build system and includes is one major pain in the ass, and cmake doesn't solve it whatsoever.

    I'm thankful for modern languages striving for simple interfaces for the build process

    rust's cargo, C#'s dotnet, go's.. go just to name a few
  • 11
    Dependencies in C are indeed not nice, BUT! it's not actually better with languages like Rust that bring a "modern" package manager because that only entices having a metric shitton of dependencies in the first place, and just like NPM, it also entices pulling in random shit from all over the internet written by stoned fuckers in whatever shithole, and then good luck with even archiving that mess so that you can build from source ten years down the road.

    Oohh you don't have to build that in ten years, right? Yeah that's because you are a millennial hipster, your head is full of rotten avocado toasts, and no you don't have ADHD, your attention span just can't rival even that of a squirrel high on crack because you're a smartphone and social media junkie.

    Now get off my lawn and let me compile shit in C.
  • 1
    Compiling shit in C is not too bad when using it in combination with CMake
  • 0
    @Fast-Nop what do rust, js and other languages have to do with C deps being not nice?
  • 4
    @kiki I explained the point for you, but I can't understand it for you.
  • 1
    @Fast-Nop no, you just spiced your insecure bitching about modern languages with populism, proving my point. Also as long as even you (unironically a C expert) agree that C deps are not nice, I can sleep happy
  • 6
    @kiki Dependencies are shit and modern languages encourage you to have as much as posible. C atleast makes you feel bad for importing shit you don't need. The next time you see somebody type import IsEven you can wish for C to slap him hard.
  • 2
    @kiki lel C deps are difficult if you cant read the first two lines of a man page.

    it takes forever to compile unless you do it right, using make or a derivative thereof.

    the framework you use, and your favorite language are all written in C-like.

    ironically your very function as a "frontend dev" (read webmaster) wouldnt exist without the creativity of people who write in C, creating frameworks for you because people like you still eat crayons, and just cant handle whats happening under the hood.

    i dont dislike JS or other high level languages because im old and grumpy but because i got much more freedom working with C, also because high level is slow as fuck and is simply unsuitable for proper programming like image parsing, math functions, OS kernel, your beloved high level languages, pretty much anything that isnt displaying a kitten on a webpage, but then it is still facilitated by C-like.

    and sophie xeon is not music, but a measure to root out epilepsia from the genepool.
  • 1
    and just thought of it:
    before you go all woke on me
    man pages arent "masculine" pages, but manual pages, accessed on unix-like systems with the command "man"
  • 4
    C is an antiquated language that needs to die for high level apps & libraries. I know, I know, hate me for it, but it's true.

    The main problem I have with it is its "raw" memory management leaves you open to memory leaks & exploits like buffer overflow attacks in a way no other vaguely modern language does. The usual reply to this is "ah, but that's the developer's fault, not the language!" Sure, but we're not just talking about idiots doing stupid stuff here. Nearly *every* major library written in C has had such flaws exposed at some point in its life - including the ones that should be secure by their very nature, like OpenSSL, libssh, etc. - this stuff is so ridiculously hard to lock down it's nearly impossible to get it right in a moderately complex project.

    Sure, for embedded stuff, or stuff where you need to get close to the bare metal, C is king. But everyone else needs to move on.
  • 4
    @AlmondSauce so youre saying that c needs to die because millenials cant deal with memory management?
    or rather: c needs to die bc ppl dont know how to use valgrind anymore?!

    find me an alternative for jump tables ,inline asm, and without having bullshit bloat like boundary checking when compiled and i will agree with you.
    oh, and it needs to be a mere step removed from asm, so that i have a clear idea what i code without disassembling the damn thing.
  • 3
    @AlmondSauce
    dont get me wrong, if i would write web apps i would use java bc i dont want to rewrite the web.
    but for everything else im using C or C++

    good example: unity, is written in c#.
    its slow as fuck and it still leaks.
    the only difference is that the problem is now hidden bc unity is proprietary.
    thats what i think of "automatisations" and "making your life easier"
  • 9
    @AlmondSauce C will never die because those who wanted to "move on" have already done so, to C++. Idiomatic C++ doesn't deal with raw pointers. Rust will not replace C because it is geared towards C++ programmers, and if C programmers had wanted that, they would long have abandoned C.
  • 4
    @bad-frog It's not just millenials - if the last few years of exploits have proved anything, it's that practically *no-one* can deal with memory management properly. I wouldn't call the openssl folks idiots that can't use valgrind, but they clearly fell into the same trap.

    And if you find a use-case for inline asm, jump tables, etc. that's *genuinely needed* these days in a high level application, sure, use C. But I've yet to find one.
  • 1
    @Fast-Nop I agree, it won't die. It's here to stay.

    But that won't stop me thinking it definitely *should* have had its day, regardless as to who actually uses the damn thing.
  • 0
    @AlmondSauce lel.
    game engine : "am i a joke to you?"
    not to mention all the fancy acronyms that would make me sound much smarter than i actually am and all the frameworks you use all the while you say c needs to die.

    as for openssl: despite the shortcomings they pulled it off, so i wont call them dumb.
    but then theres a world of difference between fixing a memory leak and a memory access exploit.

    and it isnt that you work in a high level environment that you are protected against those either.
    breaking news : google's Javascript V8 engine is written in c++, just like most other framework you could work with (c++ or C).

    the difference with openSSL is the "open" part.

    its the age old question "is many eyes, but small investment better than less eyes but on a payroll to find and fix bugs?"

    want another example?
    php injection exploit and the idiotic reason for its existence.

    and starting from a high level perspective you wouldnt find, fix, or even understand bugs if they appear.
  • 0
    @AlmondSauce im not saying that high level frameworks are inherently bad.
    when you write a game you wont be hardcoding the actors, the missions, etc, just the game engine. for the former you build a script interpreter.
    also it saves enormous amounts of time to have a common framework, obviously.

    but saying low level is bad and should die, or that the reason there are security exploits is because people use low level languages, is just stupid and ignorant.
  • 4
    @AlmondSauce I agree that C does have weaknesses - above all, I dislike the undefined behaviour in conjunction with unreliable compiler warnings. That's equivalent to a "fail open" policy. It's difficult to even find bugs if they only manifest upon a compiler update three years later.

    However, C is often belittled as portable macro assembler, and that's actually right, but that's exactly what I love about C. That's what C programmers value.

    What I'd like is a safer C (Rust is rather a safer C++), but not getting in the way like Pascal (Rust's "unsafe" escape hatch is a really good idea).
  • 1
    @Fast-Nop so... You want a low abstraction high performance safe language?

    I don't think that's possible.
    You need abstraction to encapsulate the unsafe code and present a safe interface.

    This was discussed in a podcast I think and they made way better arguments than I can reproduce here now. But maybe have a think.
  • 2
    @Geoxion Of course it is possible, depending on what exactly should go in. Managed memory and GC is out of limits of course.

    But tons of undefined behaviour should have been implementation defined in the first place, and type based pointer aliasing has always sucked. C99's "restrict" is actually useful here.

    The number one problem with buffer overflows is that arrays decay into pointers when you hand them over to a function. That loses all length information so that the compiler cannot generate a debug build with runtime checks, or a "safe" build where safety is more important than performance.

    That could be solved with "extended pointers" which are actually structs under the hood, comprised of a pointer and a length information.

    The syntax could stay just like now, i.e. dereferencing an extended pointer would actually be compiled into a double dereference, but with length check. The compiler could optimise the double dereference and the length check away for a "speed" build!
  • 2
    @Fast-Nop those are all great ideas for improving C. However, this is only a small start for memory safety.

    If you want to have full memory safety, then you need to add so many things and break so much backwards compatibility that it's not the same language anymore.
  • 2
    @bad-frog Read my post again. Low level languages shouldn't die. The use of C for high level stuff needlessly should die.

    Of course using a high level language doesn't save you from bugs and issues - but there's also certain exploits (like buffer overflow attacks) that can manifest reasonably easily in C, but are basically never a thing in higher level languages. You get at least *some* degree of protection that C doesn't give you.
  • 1
    @Fast-Nop
    im not a greybeard yet, but you can implement boundary checks if you pass the array not as an array, but a structure of the array pointer and the length of the array.
    then you could have a condition to check the pointer adresses against that value.

    or your array could be padded with 0 and be pointers so as to force segfault whenever there is an overflow (overflow = dereferencing 0). this would avoid the condition for every time you access it. but if you give the possibility to jump more than one element in your array, a "condition" is your only option, i'd say. (condition in "" bc it can be done with branchless conditionals and a jump table, and if your conditions arent too complicated, your compiler should do it for you)

    im sure there is more advanced and refined options, im no expert in security.
  • 3
    @Geoxion The typical buffer overflows have the root cause I mentioned, so most of that would get fixed this way. You don't have to be perfect because if you strive for that, things will become so complicated that C programmers will rather continue in C instead.

    And from my experience, nearly all of the bugs in my code are logic bugs or even issues on requirement or system design level. It's exceedingly rare that I have segfaults or buffer problems.

    However, I do see these issues when I review juniors' code. I'm faster to find such bugs through review than they can test, even with multi-threading. I do see the systematic appeal of Rust here which wouldn't even compile such code.

    It's just... C offers everything to me that I'd want, despite its flaws, and while I code in C, I'm thinking in assembly. I don't really want abstraction, just portability. Hence, the "portable macro assembler" trope is a compliment in my eyes, not a ridicule.

    As the saying goes, old love doesn't Rust. ^^
  • 2
    @bad-frog Yeah, of course you wouldn't need to make that a language feature because the struct way is possible right now, and you could just use some access macro to either perform the check or drop it.

    The problem is that nobody is doing that even in security relevant code.
  • 2
    @Fast-Nop incompetence makes me sad but also hopeful.
    in the land of the blind, the one eyed is king:)
  • 1
    @AlmondSauce "the use of C for high level stuff should die"
    do you have an example in mind?
  • 2
    @Fast-Nop
    and speaking of incompentence ...
    a little errata: branchless makes no sense in this particular case- branch prediction will be quite faster. but padding with 0 will still be the fastest
  • 1
    @bad-frog Using such 0 padding has the major problem that 0 cannot be a valid value. That's particularly problematic with C strings where 0 is the termination character of the payload data. If you have a small string in a large array, you can append another string, after all.
  • 0
    @Fast-Nop the trick is to use an array of pointers.
    so that you need to dereference the array element to acess it.
    and if you dereference 0: thats a segfault.
    no condition, no branch prediction misses.
    just linear code at the cost of an additionnal dereferencing :)
  • 1
    @bad-frog That would basically ruin cache performance, similarly to linked lists or objects sprayed throughout the heap, and blow up the arrays by a factor of up to nine (64 bit pointers, char element).

    Also, it would IMO not solve the problem because what happens if you have an array of length 128, use 42 entries initially and then want to add entry 43? That would lose functionality. And if you solve that, how do you prevent the overflow when instead accessing element 129?
  • 0
    @Fast-Nop well, didnt exactly think that through.

    the idea i had was to create a contiguous, defined area for a string, that could be navigated using incrementations, all the whilst avoiding the use of a condition.

    and if i understand things right, the issue of cache performance would be relevant if we are talking about rather large strings? right?
  • 0
    @Fast-Nop i think i get it.
    if fetching the data is the issue could it be that instead of allocating the "master array", then looping through it and allocating the chars

    if you :
    allocate the master array,
    allocate the sub array as a whole,
    bzero master array
    then loop through the master array starting at 1 and ending at size -1 and setting the values of the master array to the adresses of the sub array, it would solve the problem, right?

    fuck cant make it explicit enough
    ill post my code it would be easier for me i think
  • 0
    char *array[10];
    char **start = &(array[1]);
    char *str
    ...

    bzero array

    ...

    // intitializing the array
    while (size--)
    {
    start[size] = &(str[size]);
    }
  • 1
    @bad-frog Ah that's how you mean, basically having a layered thing. That would require initialising the master array (address layer), i.e. a considerable performance hit on top of the increased cache pressure due to more memory consumption. And it would also inhibit instruction level parallelism because the access order would be strictly sequential. However, if that could be disabled for "speed" release build, it wouldn't be that bad.

    However, then you can as well have the struct approach with the length contained. Besides taking less RAM, this could also catch non-sequential out of bounds access.
  • 1
    @Fast-Nop lel. like i suspected.
    "probably useless... but its boundary checked!":p
  • 0
    @inawhile Because that would be a division upon every access, and while it would prevent the OOB access, it would still lead to strange runtime errors which wouldn't be nice to debug. Something like an immediate access upon OOB would be better.
  • 0
    @inawhile
    edit: take it with a grain of salt, it seems a better option is possible
    afaik if the modulo is a power of 2 its pretty fast because its a bitwise shift in disguise.
    hadnt checked it yet, im barely beginning learning asm, and even that is an overstatement.

    and i couldnt tell whether a condition or other modulo is faster.

    what i know, however is that you could tackle the negative problem using a branchless
    conditionnal (if thats what its called)

    you could write:

    x = arr->buff[(((uint)i) % arr->size) * (x > 0)]

    if x is smaller than 0, it evaluates to 0 and then you multiply your index by it, which gives an index of 0.
    otherwise it evaluates to 1 and your index is "as is"

    as for the otclassing part, im not so sure about that. i know stuff i use for my projects, but not much else:)

    edit: the prophet @FastNop hath spoken. now im googling again:p

    re-edit: what is OOB?
  • 1
    @bad-frog Yes, for power of two sizes, the modulo will be compiled into a bitwise AND - but not for other sizes. OOB = out of bounds. Or out of body, but that takes more than C programming. ;-)
  • 1
    @Fast-Nop everything is clear now.
    hail the Fast-Nop!
  • 1
    @inawhile id say thats the spirit.
    you cant be sure until you look under the skirt, innit?
  • 4
    @inawhile That's why I look through the ISA and instruction timings when I target a CPU architecture where performance isn't abundant. It's also why I like C because I have a pretty good guess as to what the compiler may generate.

    That's different from languages where you code so high in some abstract void that you need your own oxygen supply to even breathe.
  • 2
    @Fast-Nop "...coding so high you need your own oxygen supply..."
    good one
  • 1
    @Fast-Nop I am not gonna lie. Sometimes I have oxygen deprivation while coding C++.
Add Comment