I fucking love C++?

I fricking love C++, IQfy. You can make it do anything. For example here, a Zig/Go style defer!
using DF = std::function<void()>;

class Deferer {
private:
DF f;
public:
Deferer(DF f) {
this->f = f;
}
~Deferer() {
if (this->f)
this->f();
}
};

void test() {
FILE *fp = fopen("test.txt", "wb");
Deferer _d([=]() { fclose(fp); });
}

int main() {
test();
}

Beware Cat Shirt $21.68

Rise, Grind, Banana Find Shirt $21.68

Beware Cat Shirt $21.68

  1. 1 month ago
    Anonymous

    What is the point of defer if you already have RAII?

    • 1 month ago
      Anonymous

      arbitrary statements. what if you are using a C library with many different objects and don't want to wrap every single one in a class?

    • 1 month ago
      Anonymous

      >Deferer _d([=]() { fclose(fp); });
      #define defer(X) Deferer _d([=]() { X })

      void test() {
      FILE *fp = fopen("test.txt", "wb");
      defer( fclose(fp) );
      // ...
      }

      fixed

      >What is the point of defer if you already have RAII?
      actually this
      defer is a solution to a problem existing only in inferior languages (everything but C++)

      • 1 month ago
        Anonymous

        God I love macros.

        • 1 month ago
          Anonymous
        • 1 month ago
          Anonymous

          >Goddess I love macros.

          • 1 month ago
            Anonymous

            uh she is a bit too large, don't you think?

          • 1 month ago
            Anonymous

            Just like C++

          • 1 month ago
            Anonymous

            oh snap

          • 1 month ago
            Anonymous

            >uh she is a bit too large, don't you think?
            not at all

          • 1 month ago
            Anonymous

            uhhh do you have more? was this AI generated?

          • 1 month ago
            Anonymous

            Yes. Yes.

          • 1 month ago
            Anonymous

            Nice. The fingers are no longer a problem it seems

          • 1 month ago
            Anonymous

            [...]

            I'm just glad corporations will be able to make their globohomosexual 3d art and animation cheaper than ever now. I love technology.

          • 1 month ago
            Anonymous

            how is it globohomo?

          • 1 month ago
            Anonymous

            do you have some text story to go along with it that you then use for "research purposes"?

          • 1 month ago
            Anonymous

            no, but the story is pretty simple. imagine a horny milf can shrink a student and take him home without anyone noticing. imagine what she is going to do with him.

          • 1 month ago
            Anonymous

            damn you are like me

          • 1 month ago
            Anonymous

            the only question remains: which hole?

          • 1 month ago
            Anonymous

            obviously it has to start with the mouth and then go down from there

          • 1 month ago
            Anonymous

            the only question remains: which hole?

            another question: is he ever going out or is he a single-use toy

          • 1 month ago
            Anonymous

            obviously she needs to grind on him for a little while because she can't just take student after student without anyone noticing. maybe one every year

          • 1 month ago
            Anonymous

            imagine being locked in her toy drawer for the entire day waiting for her to return from work eager to use you

          • 1 month ago
            Anonymous

            the only question remains: which hole?

            [...]
            another question: is he ever going out or is he a single-use toy

            another question: how small is he?

          • 1 month ago
            Anonymous

            >another question: how small is he?
            we need to know

          • 1 month ago
            Anonymous
          • 1 month ago
            Anonymous

            Yes. Yes.

          • 1 month ago
            Anonymous

            Yes. Yes.

            [...]

            C++ allowed that

          • 1 month ago
            Anonymous

            Python allowed that

          • 1 month ago
            Anonymous

            Python is way too slow. It's all C++. Python is just a CLI for the real thing.

            obviously it has to start with the mouth and then go down from there

            down but which way?

          • 1 month ago
            Anonymous

            Anyone knows any good stories to read for this

          • 1 month ago
            Anonymous

            what stories? read for what?

          • 1 month ago
            Anonymous

            This

            no, but the story is pretty simple. imagine a horny milf can shrink a student and take him home without anyone noticing. imagine what she is going to do with him.

            but longer and with pics. I don't even know how this category is called

          • 1 month ago
            Anonymous

            why would you like to read such stories?

          • 1 month ago
            Anonymous

            ( ͡° ͜ʖ ͡°)

          • 1 month ago
            Anonymous

            Yes. Yes.

            [...]

            explain these to me

      • 1 month ago
        Anonymous

        >#define defer(X) Deferer _d([=]() { X })
        actually this wouldn't work
        but it can be done beautifully
        frick, you are rustling my autism to code this...

        • 1 month ago
          Anonymous

          right, it would need a random number or something

      • 1 month ago
        Anonymous

        God I love macros.

        >Just use VA_ARGS
        it won't work for blocks of code
        >_d
        can't have multiple defers

        >#define defer(X) Deferer _d([=]() { X })
        actually this wouldn't work
        but it can be done beautifully
        frick, you are rustling my autism to code this...

        >frick, you are rustling my autism to code this...
        done:

        https://godbolt.org/z/aKMfq7WWx

        and the asm optimizes out completely, as expected from based C++ and GCC

        • 1 month ago
          Anonymous

          simpler, without std:
          https://godbolt.org/z/xs8c541KE

          • 1 month ago
            Anonymous

            Now try to use a local variable

        • 1 month ago
          Anonymous

          simpler, without std:
          https://godbolt.org/z/xs8c541KE

          Now try to use a local variable

          fixed:
          https://godbolt.org/z/aGaK7j1M8

          • 1 month ago
            Anonymous

            It's insane how good the gcc optimizer is

        • 1 month ago
          Anonymous

          simpler, without std:
          https://godbolt.org/z/xs8c541KE

          Now try to use a local variable

          [...]
          [...]
          fixed:
          https://godbolt.org/z/aGaK7j1M8

          and, oh, capture by reference:

          https://godbolt.org/z/6EqYzfo3z

          It's insane how good the gcc optimizer is

          >It's insane how good the gcc optimizer is
          Yes.

        • 1 month ago
          Anonymous

          I lost, holy shit

  2. 1 month ago
    Anonymous

    >([=]())
    Explain.

    • 1 month ago
      Anonymous

      Lambda, captured by value.

    • 1 month ago
      Anonymous

      So, this is a lambda syntax. lambdas oblviously need code blocks, hence {}.
      Lambdas also can take parameters, that's why (), because lambdas are just inline anonymous functions.
      Lambdas in C++, because it is a garbage collected language cannot interact with the environment (local variables) by default. Hence we have the [] to specify capturing. The empty [] means no capturing which is the default, but you can use many things in there, for example you can do [fp] which captures fp so that it can be used inside the closure. you can use [=] which will capture all used variables by value automatically, or [&] which will capture references to that variables (useful for large objects)

      • 1 month ago
        Anonymous

        >because it is a garbage collected language cannot interact with the environment (local variables) by default
        lol what

        • 1 month ago
          Anonymous

          because it is *NOT* garbage collected

      • 1 month ago
        Anonymous

        >Lambdas in C++, because it is a garbage collected language cannot interact with the environment (local variables) by default.
        Subtle, tasteful.
        8/10. This one is up there.

        https://i.imgur.com/WZxK7FY.png

        I fricking love C++, IQfy. You can make it do anything. For example here, a Zig/Go style defer!
        using DF = std::function<void()>;

        class Deferer {
        private:
        DF f;
        public:
        Deferer(DF f) {
        this->f = f;
        }
        ~Deferer() {
        if (this->f)
        this->f();
        }
        };

        void test() {
        FILE *fp = fopen("test.txt", "wb");
        Deferer _d([=]() { fclose(fp); });
        }

        int main() {
        test();
        }

        C++ related question, is Stroustrup's PPP worth reading if you aren't a beginner to the language, or should I just re-read the C++ programming language instead?

        >Deferer _d([=]() { fclose(fp); });
        #define defer(X) Deferer _d([=]() { X })

        void test() {
        FILE *fp = fopen("test.txt", "wb");
        defer( fclose(fp) );
        // ...
        }

        fixed

        >What is the point of defer if you already have RAII?
        actually this
        defer is a solution to a problem existing only in inferior languages (everything but C++)

        >defer is a solution to a problem existing only in inferior languages (everything but C++)
        It can enable a certain style of hyper-transparent programming.

    • 1 month ago
      Anonymous

      In rust this is just
      >move ||

      • 1 month ago
        Anonymous

        in rust it also wouldn't work because it doesn't live long enough (the variable)

        • 1 month ago
          Anonymous

          What? You're passing ownership of the object to the lambda.

          • 1 month ago
            Anonymous

            >What? You're passing ownership of the object to the lambda.
            and what if you use it after the defer statement? huh?

        • 1 month ago
          Anonymous

          You can do it in Rust, like

          use std::{io, process::ExitCode};

          pub struct FnGuard<F: FnOnce()>(Option<F>);

          impl<F: FnOnce()> Drop for FnGuard<F> {
          fn drop(&mut self) {
          self.0.take().unwrap()();
          }
          }

          macro_rules! defer {
          ($($body:tt)*) => {
          let _guard = FnGuard(Some(|| {{ $($body)* };}));
          };
          }

          fn main() -> ExitCode {
          defer! { println!("Goodbye") };
          println!("Hello");

          let fp = unsafe { libc::fopen(c"test.txt".as_ptr(), c"rb".as_ptr()) };
          if fp.is_null() {
          eprintln!("{}", io::Error::last_os_error());
          return ExitCode::FAILURE;
          }
          defer! { unsafe { libc::fclose(fp) } };

          ExitCode::SUCCESS
          }

          has shown.

          The limitation is that whatever you reference in the deferred block, will stay referenced and you won't be able to mutate, drop or move. This shouldn't be a problem as in general case you would just reference handles that are Copy, but more complex use cases could fail. Maybe you could overcome it with some std::pin and/or unsafe, but still this sort of feature would be very hard to implement without any unsoundness. In Rust, values can be dropped at any time, moved out, get passed to other threads and making it work well with referenced would be pretty hard.
          There is no need to use that stop gap feature if you have a fully fledged RAII.

          What? You're passing ownership of the object to the lambda.

          You are right on this, but that would make this sort of deref useless. You generally want to access the thing that deref will cleanup after if something goes wrong. Having thing executed at the end of the scope without any way to access it in the meantime is useless.

          • 1 month ago
            Anonymous

            Yeah, Rust is a nightmare.

          • 1 month ago
            Anonymous

            it is good for what it was intended. kernels and command line utilities.

          • 1 month ago
            Anonymous

            How is this good for command line utilities? You could make those "memory safe" by not calling free() in the few milliseconds they run.

            Kernel? Hahahaahahahahahahahahahaha

          • 1 month ago
            Anonymous

            no, it's that the structure of kernels and cmd utilities means that there isn't much of a global state so borrow checker isn't a problem and you can use the nice features rust otherwise offers

          • 1 month ago
            Anonymous

            First time seeing static analysis?

          • 1 month ago
            Anonymous

            There are tons of static analysis tools for C++. I use them daily.

          • 1 month ago
            Anonymous

            Then you should be able to understand why is it hard to write something like that in a provably correct way.

          • 1 month ago
            Anonymous

            With actual formal methods instead of troony cargo-culting.

          • 1 month ago
            Anonymous

            Your response doesn't make sense.

          • 1 month ago
            Anonymous

            Filtered

  3. 1 month ago
    Anonymous

    Programming and principles using C++ filtered me.

  4. 1 month ago
    Anonymous

    i wish i could get this excited about language features again. programming is still very enjoyable to me, but i just dont give a shit about language features and syntax sugar anymore. i feel like i've seen it all (even though i know i haven't).

  5. 1 month ago
    Anonymous

    Good idea creating one that takes an arbitrary function, but we call it a scope guard in C++

  6. 1 month ago
    Anonymous

    Bloated.
    Might as well just use a language with GC at this point.
    https://godbolt.org/z/7j9MPdfcM

    • 1 month ago
      Anonymous

      >use one defer statement? might as well garbage collect everything
      moron

      • 1 month ago
        Anonymous

        OP's implementation is extremely bloated. std::function is an extremely costly type-erased atomic object.
        Also why write all that when you could just
        std::unique_ptr<void> _(nullptr, []() do_the_thing(); ));

        • 1 month ago
          Anonymous

          because we declare one class to get rid of that nullptr forever. also we save one CPU cycle because we don't decrement refcnt on destruct

          • 1 month ago
            Anonymous

            unique_ptr is not refcounted

          • 1 month ago
            Anonymous

            You can declare a templated class that wraps the nullptr. It will be more lightweight than a std::function in any case. Just godbolt it, you'll see.

            >#define defer(X) Deferer _d([=]() { X })
            actually this wouldn't work
            but it can be done beautifully
            frick, you are rustling my autism to code this...

            Just use VA_ARGS

          • 1 month ago
            Anonymous

            >Just use VA_ARGS
            it won't work for blocks of code
            >_d
            can't have multiple defers

          • 1 month ago
            Anonymous

            use __COUNTER__

          • 1 month ago
            Anonymous

            This is the point where clever macroshit becomes detrimental. Better ask the user to give a name to each defer handle than end up with weird names when you're trying to debug.

          • 1 month ago
            Anonymous

            >Better ask the user to give a name to each defer handle
            absolutely disgusting

          • 1 month ago
            Anonymous

            >I don't want my backtraces to be readable
            nocoder

          • 1 month ago
            Anonymous

            Only shared_ptr is ref counted.

            I beg to differ.

            Now show MSVC.
            Its only GCC's lib that is literally brain aids to read due to their inane identifier naming and indentation rules.
            >It's why all the C++ replacements (including cppfront) are a dead end.
            You're calling it a dead end even though its been announced for less than a year? And even though you can still use it within the same file as full fledged C++?

          • 1 month ago
            Anonymous

            >Now show MSVC.
            >proprietary compiler
            Lmao @ ciniles

          • 1 month ago
            Anonymous

            I thot Microsoft's STL was libre now

        • 1 month ago
          Anonymous

          >Deferer _d([=]() { fclose(fp); });
          #define defer(X) Deferer _d([=]() { X })

          void test() {
          FILE *fp = fopen("test.txt", "wb");
          defer( fclose(fp) );
          // ...
          }

          fixed

          >What is the point of defer if you already have RAII?
          actually this
          defer is a solution to a problem existing only in inferior languages (everything but C++)

          It's already built into the language, called a smart pointer.
          std::unique_ptr<std::FILE, decltype(&std::fclose)> fp(std::fopen("test.txt", "wb"), &std::fclose);

          mate, wtf are you doing

          using ScopedFile = std::unique_ptr< FILE, void(*)(FILE*)>;

          auto handle = ScopedFile{ fopen("test.txt", "wb"), fclose };

          Or you could use the GSL like an actual C++ programmer.
          >b-but muh competent p-
          I don't care. Begone, nocoder.

          • 1 month ago
            Anonymous

            "Actual" as in existing in the real world or "actual" as in what C++ programmers ought to be? What's the GSL's adoption rate?

          • 1 month ago
            Anonymous

            >"Actual" as in existing in the real world or "actual" as in what C++ programmers ought to be?
            I'll give you a hint if you can call it one: neither uses fopen in C++ code.

            >What's the GSL's adoption rate?
            Irrelevant.

          • 1 month ago
            Anonymous
          • 1 month ago
            Anonymous

            >"Actual" as in existing in the real world or "actual" as in what C++ programmers ought to be?
            I'll give you a hint if you can call it one: neither uses fopen in C++ code.

            >What's the GSL's adoption rate?
            Irrelevant.

            Oh yeah the GSL is so good
            >Point number 28637184:
            >you should NEVER use this pattern, it's complete doodoo
            >here's what you should do instead
            >use gsl::wienersuk()
            >*note: gsl::wienersuck() isn't implemented yet

    • 1 month ago
      Anonymous

      Reminder that, for programs with many objects having non-scoped lifetimes, GC is usually more efficient AND more correct.

      Whenever you use some form of reference counting in a non-GC language, you are basically admitting this.

    • 1 month ago
      Anonymous

      Optimised.
      Not a single class instantiated.

      https://godbolt.org/z/WM33hErGM

      • 1 month ago
        Anonymous

        [...]
        [...]
        [...]
        >frick, you are rustling my autism to code this...
        done:

        https://godbolt.org/z/aKMfq7WWx

        and the asm optimizes out completely, as expected from based C++ and GCC

        HOLY BASED

    • 1 month ago
      Anonymous

      that's because std::function i heavy af, and op is a newb. the correct way to do this is by making deferer a template

      template<class DF>
      struct Deferer {
      DF f;
      Deferer(DF f) : f(f) {
      }
      ~Deferer() {
      f();
      }
      };

      • 1 month ago
        Anonymous

        this should work

        [...]
        [...]
        [...]
        and, oh, capture by reference:

        https://godbolt.org/z/6EqYzfo3z

        [...]
        >It's insane how good the gcc optimizer is
        Yes.

        • 1 month ago
          Anonymous

          it works, but there is no point to all the macro bloat. you will never see something like that besides in a toy project. tbh even the deferer class is bloat, you would just use unique_ptr with a custom deleter.

          • 1 month ago
            Anonymous

            unique pointer uses a std::function and doesn't optimize

          • 1 month ago
            Anonymous

            not true
            https://godbolt.org/z/EdPE5sjPo

          • 1 month ago
            Anonymous

            https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.4/a01404.html
            Show me the function.

          • 1 month ago
            Anonymous

            Not necessarily, my boy mCoding has a video on it.

            not true
            https://godbolt.org/z/EdPE5sjPo

            >-O3
            Now try printing sizeof fp, it will be 16, because it also stores the function pointer. You can avoid this by using a deleter in the template, but not passing it as a parameter to the constructor:
            typedef decltype([](auto fp) { std::fclose(fp); }) Deleter;
            std::unique_ptr<std::FILE, Deleter> fp(std::fopen("test.txt", "wb"));

  7. 1 month ago
    Anonymous

    WHAT THE FRICK IS THIS LOGO OP
    Also buddy, you can implement defer in C, see the STC implementation.
    #define c_defer(...)
    for (int _i = 1; _i; _i = 0, __VA_ARGS__)
    It's used like that:
    // `c_defer` executes the expression(s) when leaving scope.
    cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world");
    c_defer (cstr_drop(&s1), cstr_drop(&s2))
    {
    printf("%s %sn", cstr_str(&s1), cstr_str(&s2));
    }

    • 1 month ago
      Anonymous

      that is not the same, in your case you have to define defer outside the scope which means one more level of nesting. you cannot do what OP did and what Zig does which is a defer statement in the middle of existing code block.

      • 1 month ago
        Anonymous

        Fair enough. In the real world I use __attribute__((cleanup(*~~ anyway
        >muh poortability
        Fix your compiler.

        • 1 month ago
          Anonymous

          I mean that sounds like gcc but I am sure clang supports it too and I don't think anyone uses anything else

    • 1 month ago
      Anonymous

      I think a proper way to implement defer in C would use setjmp/longjmp

    • 1 month ago
      Anonymous

      Neat, it resembles with-* style macros in Lisp.

      While not as powetful as Lisp's, C preprocessor macros are ridiculously underrated, 90% of Sepples features become completely unnecessary with good use of macros.

      • 1 month ago
        Anonymous

        Yes and those macros are notoriously hard to debug and cause more headaches than not, which is why they are banned in most code bases and Linux is moving towards C++ and Rust specifically because of ugly 100+ line macros that nobody knows what they do

        • 1 month ago
          Anonymous

          >Yes and those macros are notoriously hard to debug and cause more headaches than not
          Yes, this is the universal consensus by people who don't program and only talk about programming on the internet, but I don't see how that is relevant.

          >which is why they are banned in most code bases and Linux is moving towards C++
          In what universe do you live in?

    • 1 month ago
      Anonymous

      // `c_defer` executes the expression(s) when leaving scope.
      cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world");
      c_defer (cstr_drop(&s1), cstr_drop(&s2))
      {
      break; // lol
      printf("%s %sn", cstr_str(&s1), cstr_str(&s2));
      }

      • 1 month ago
        Anonymous

        well yeah, don't do that

      • 1 month ago
        Anonymous

        >break off a block
        >Exit instructions don't get executed
        Seems like the expected outcome to me.

        • 1 month ago
          Anonymous

          No, it absolutely isn't. The point of defer/destructors is to execute something when exiting a scope regardless of how we exit.

          well yeah, don't do that

          Yeah I won't do that (use C).

          • 1 month ago
            Anonymous

            >Yeah I won't do that (use C).
            why?

          • 1 month ago
            Anonymous

            I just don't like it when C++ doesn't really prevent me from writing actual C, but when I need some reasonably high level feature I am not forced into hacking together an ugly #define.

          • 1 month ago
            Anonymous

            C++ still provides no way to split a string. Why not use an actual high level language, then? You can call existing C code from any language.

    • 1 month ago
      Anonymous

      #include <setjmp.h>
      #include <stdio.h>

      #define _defer_symb_comb(a, b) a ## b
      #define _defer_symb(a, b) _defer_symb_comb(a, b)

      static jmp_buf _defer_return_loc = {0};
      static jmp_buf _deferrals[1] = {0};
      static volatile unsigned char _num_deferrals = 0;

      #define DEFER_MAX 8
      #define deferral
      volatile unsigned char _num_deferrals = 0;
      jmp_buf _defer_return_loc = {0}, _deferrals[DEFER_MAX] = {0}

      #define defer
      for(int _defer_symb(_defer_n_, __LINE__) = 0;
      _defer_symb(_defer_n_, __LINE__) < 3;
      _defer_symb(_defer_n_, __LINE__)++)
      if(!_defer_symb(_defer_n_, __LINE__)) {
      printf("n_%d set 0n", __LINE__);
      if(!setjmp(_deferrals[_num_deferrals++])) {
      printf("n_%d %d aftern", __LINE__, 1);
      break;
      }
      }
      else if(_defer_symb(_defer_n_, __LINE__) == 2) {
      printf("n_%d endn", __LINE__);
      _defer_symb(_defer_n_, __LINE__) = 3;
      if(_num_deferrals) {
      longjmp(_deferrals[--_num_deferrals], 1);
      } else {
      longjmp(_defer_return_loc, 1);
      }
      }
      else

      #define return
      if(!setjmp(_defer_return_loc)) {
      if(_num_deferrals) longjmp(_deferrals[--_num_deferrals], 1);
      goto _defer_symb(_return_goto, __LINE__);
      } else _defer_symb(_return_goto, __LINE__): return

      int fn()
      {
      deferral;
      defer {
      printf("secondn");
      }
      defer {
      printf("firstn");
      }
      return 1;
      }

      • 1 month ago
        Anonymous

        >for
        what if I use a return statement in defer?

        • 1 month ago
          Anonymous

          the macro overrides return so you can safely call return in defer

      • 1 month ago
        Anonymous

        abominable

        • 1 month ago
          Anonymous

          yeah, defer really is abomination and should not be used in any language

  8. 1 month ago
    Anonymous

    It's already built into the language, called a smart pointer.
    std::unique_ptr<std::FILE, decltype(&std::fclose)> fp(std::fopen("test.txt", "wb"), &std::fclose);

  9. 1 month ago
    Anonymous

    And in classic C++ fashion, I'm pretty sure you've just introduced a bug related to exception safety. std::function's assignment operator can throw.

    • 1 month ago
      Anonymous

      Literally don't throw exceptions in that code. You already know its a destructor, your freeing functions shouldn't throw anyway, so why do little b***h homosexuals (you) insist on complaining about non issues?

      Are you a little b***h homosexual? Yes you are, lmao.

      • 1 month ago
        Anonymous

        Meds. If the constructor of the Deferer throws (which it can because of the std::function), the file will not be closed.
        >Yeah but it usually doesn't.
        And sepplesBlack folk wonder why people don't trust them.

        • 1 month ago
          Anonymous

          this is a bug that is easily caught and shouldn't happen in the first place because you are supposed to look at documentation, not just throw random shit into constructors

          • 1 month ago
            Anonymous

            >this is a bug that is easily caught
            Then why didn't OP?

    • 1 month ago
      Anonymous

      OP is doing stupid shit. This is how you do it:

      mate, wtf are you doing

      using ScopedFile = std::unique_ptr< FILE, void(*)(FILE*)>;

      auto handle = ScopedFile{ fopen("test.txt", "wb"), fclose };

  10. 1 month ago
    Anonymous

    mate, wtf are you doing

    using ScopedFile = std::unique_ptr< FILE, void(*)(FILE*)>;

    auto handle = ScopedFile{ fopen("test.txt", "wb"), fclose };

    • 1 month ago
      Anonymous

      that is not a defer statement

      • 1 month ago
        Anonymous

        WTF are you on about. That "defer statement" OP hacked together is nothing more that a convoluted a scoped function object. If you want RAII behaviour for C pointers using a unique_ptr with a custom deleter is the way to do it.

        • 1 month ago
          Anonymous

          OP proved that C++ is a very free language that can do anything you want it to. Why are you autisming over this

          • 1 month ago
            Anonymous

            >use one cleanup feature to emulate another cleanup feature
            Not great proof of unlimited power, maybe show off some template abuse instead

          • 1 month ago
            Anonymous

            Why are you upset C++ is better than your shit-lang? Your post reeks of seethe.

          • 1 month ago
            Anonymous

            My shit-lang of choice can do this exact thing too but it can't do template abuse, that's why I said to show off template abuse

    • 1 month ago
      Anonymous

      OP proved that C++ is a very free language that can do anything you want it to. Why are you autisming over this

      This is actually one of the key things that makes C++ so awful to use in practice. There's 50 different ways to do something and an idiosyncratic std way was added in some recent standard but people still do these hacked together monstrosities because "muh freedom". Every C++ library is basically written in its own dialect because everyone thinks their way is the best.

      • 1 month ago
        Anonymous

        that is a fine thing for a language that's supposed to cover every single base
        for less bloat turn to c

        • 1 month ago
          Anonymous

          obsolete by zig

  11. 1 month ago
    Anonymous

    >[=]()
    what the frick is this abomination
    idk what std::function<void> is either. is it just a reference to a void function? why u need this. what if you want to get return value

    • 1 month ago
      Anonymous

      when does a defer function have a return value lmao

    • 1 month ago
      Anonymous

      >Hurr, I don't know the language so I don't know how to read it therefore it is bad
      The biggest advocate for C++ is that the vast majority of "people" who criticize it are sub 80 IQ.

      • 1 month ago
        Anonymous

        Explaining lambda captures in Sepples only makes it look even more embarrassing, which is why you yourself conveniently chose not to do it.

  12. 1 month ago
    Anonymous

    use std::{io, process::ExitCode};

    pub struct FnGuard<F: FnOnce()>(Option<F>);

    impl<F: FnOnce()> Drop for FnGuard<F> {
    fn drop(&mut self) {
    self.0.take().unwrap()();
    }
    }

    macro_rules! defer {
    ($($body:tt)*) => {
    let _guard = FnGuard(Some(|| {{ $($body)* };}));
    };
    }

    fn main() -> ExitCode {
    defer! { println!("Goodbye") };
    println!("Hello");

    let fp = unsafe { libc::fopen(c"test.txt".as_ptr(), c"rb".as_ptr()) };
    if fp.is_null() {
    eprintln!("{}", io::Error::last_os_error());
    return ExitCode::FAILURE;
    }
    defer! { unsafe { libc::fclose(fp) } };

    ExitCode::SUCCESS
    }

  13. 1 month ago
    Anonymous

    Yet you can't split a string.

    • 1 month ago
      Anonymous

      #include <iomanip>
      #include <iostream>
      #include <ranges>
      #include <string_view>

      int main()
      {
      using std::operator""sv;
      constexpr auto words{"Hello^_^C++^_^20^_^!"sv};
      constexpr auto delim{"^_^"sv};

      for (const auto word : std::views::split(words, delim))
      // with string_view's C++23 range constructor:
      std::cout << std::quoted(std::string_view(word)) << ' ';
      std::cout << 'n';
      }

      • 1 month ago
        Anonymous

        >delim{"^_^"sv};
        > ^_^
        hardcore cringe/10.

        • 1 month ago
          Anonymous
      • 1 month ago
        Anonymous

        >range constructor
        Aren't you supposed to use
        std::string_view(std::from_range, word)
        or
        word | ranges::to<std::string_view> ?

      • 1 month ago
        Anonymous

        What language is this?

        • 1 month ago
          Anonymous

          That's modern C++ babey

  14. 1 month ago
    Anonymous

    are you that same moronic fricking moron that tried and failed with that c puzzle? because the text formatting is exactly the same. you can't code. frick off, larping moron.

    • 1 month ago
      Anonymous

      which one? that formatting is the only correct one so it is very widely used

  15. 1 month ago
    Anonymous

    The problem with your approach is that it doesn't behave like the defer statement in the language you mention.
    In Zig and other language, deferred statements are executed in the reverse order of how they're declared.

    • 1 month ago
      Anonymous

      Destructors do that too for much the same reason

  16. 1 month ago
    Anonymous

    Nah, Java is a lot better.

  17. 1 month ago
    Anonymous

    Destructors and RAII are an amazing feature that those OO programmers that havent experienced it cant fathom what they are missing.

    I havent written cpp in over a decade and i still miss deterministic code while using these GC languages.

    • 1 month ago
      Anonymous

      Stupid as all frick. In C# I can call
      obj.Dispose()
      obj.Finalize()
      GC.Collect()

      And the fricking garbage collector will still just twiddle its thumbs and leave it in memory for as long as it wants.

      • 1 month ago
        Anonymous

        This. I was making a video game in C#, and these three fricking functions you posted never actually helped me with unloading resources.

        • 1 month ago
          Anonymous

          Why do you think that resource heavy objects like Bitmaps have a Dispose method? Lmao

          • 1 month ago
            Anonymous

            My understanding is that there's a lot of reference count going on in the background. But after a lot of research, I come to find out that the timing of GC is always on a "just depends" basis. Nothing deterministic. Nothing actual. Just "when it can."

          • 1 month ago
            Anonymous

            Exactly. Even calling all 3 methods, the most you get is to put the object on the finalize queue. But it's a mystery when the gc will actually start processing it. Infuriating that there's no way to override it and say, I know what I'm doing clean this up now.

    • 1 month ago
      Anonymous

      Destructors and RAII are merely mechanisms to implement scope-based guaranteed cleanup, they are not magic.

      However, once you have objects with non-trivial lifetimes, GC is better.

      • 1 month ago
        Anonymous

        >However, once you have objects with non-trivial lifetimes, GC is better.
        Wrong.
        Smart Pointers are the answer.
        GC is shit. It's a process that fires randomly and always fails to do it in the right time. Or doesn't execute at all for a long time and then runs and takes up all resources for an hour (real life problem we had). GC is... garbage.

        • 1 month ago
          Anonymous

          >and takes up all resources for an hour
          what shitlang are you using?

          • 1 month ago
            Anonymous

            Java
            C# is even worse with its bugs and issues.

          • 1 month ago
            Anonymous

            garbage collecting should only take a few ms
            if you had hour long slowdowns it was your code at fault, not the language or gc

          • 1 month ago
            Anonymous

            >if you had hour long slowdowns it was your code at fault, not the language or gc.
            oh, of course, homosexual.

            a very simple micro-service that collected data from sockets, processed them and spat them out.
            each data chunk was created, processed and then left for the GC to reclaim.

            had like 64GB of RAM to waste on a VM.
            used it all up in 24h-48h and then started to reclaim everything aggressively stopping the data processing.

            no data processed = VM considered dead, so it was killed by load balancer.
            anyway, not killing it and waiting for 1h was still an unacceptable solution.

            result:
            lots of data lost from the time of GC working.
            multiply by like 10 VMs running those.

            we ended up rewriting the whole thing in C++.
            constant memory usage, because memory freed right after it was processed.
            also general speedup because C++.
            we reduced VMs from 10 with 64GB of RAM to 3 with 16GB or RAM.
            saved thousands of dollars in the test environment and probably hundreds of thousands in production where they had 100x the traffic (and 1000 -> 300 VMs).

            Java is a piece of crap (and C#/dotnet is even worse). Just use C++.

          • 1 month ago
            Anonymous

            >a very simple micro-service that collected data from sockets, processed them and spat them out.
            >each data chunk was created, processed and then left for the GC to reclaim.
            You are a stupid. Clearly you had dangling references in some singleton object that was preventing the GC from doing its job. Took it an hour just to unfrick your shit when system usage crossed a threshold. Either that or you configured the GC incorrectly. It's not the garbage collector's fault you are incompetent.

          • 1 month ago
            Anonymous

            You have zero understanding of memory management and only parrot internet memes.

            Smart pointers generate boilerplate caused by having to handle exceptions (yes, even unique_ptr). shared_ptr uses reference counting, which is awful and can't handle cyclic references, which a proper tracing GC can. Let alone that neither allow memory compaction, which GC trivially allows.

            >always fails to do it in the right time. Or doesn't execute at all for a long time and then runs
            All forms of dynamic memory management have this problem, precisely because performance is unpredictable. Even a simple call to malloc(3) has unpredictable performance. If latency was that critical, you and your team were idiots for using dynamic allocation at all in that project (assuming it ever existed). This is why dynamic allocation is wholesale banned in MISRA, for instance.

            If your program has extremely tight timing constrains, GC is not appropriate, but neither is manual dynamic memory management. If it doesn't have such requirements, GC is better in every way.

            dubs of truth

          • 1 month ago
            Anonymous

            of course, the entire department was incompetent, every single Senior Java dev
            *IF* they were all just incompetent (which they weren't), then I have some bad news about the state of Java programming as a whole.
            also it seems C#/dotnet dev are similarly incompetent with all the problems this buggy environment causes in real world applications.
            sure, Java and C# look great for Hello World programs. that's how they buy companies. idiots decide Java/C# is better. but in real world it is absolute trash.

          • 1 month ago
            Anonymous

            skill issue
            >of course, the entire department was incompetent, every single Senior Java dev
            sure looks that way

          • 1 month ago
            Anonymous

            >of course, the entire department was incompetent, every single Senior Java dev
            What's with the sarcasm? What makes you think this isn't a very real possibility?

          • 1 month ago
            Anonymous

            If hour long gc pauses were unavoidable with simple microservices that only processed data from sockets, it would be unusable by anybody for just about anything. The problem is clearly with the shitheap you created.

          • 1 month ago
            Anonymous

            if it's a constant flow of data with max bandwidth saturation?
            probably every implementation using a non-deterministic GC will die. allocation and processing must be synchronized so that you get a predictable results. can process N chunks of data at a time, will allocate no more than N chunks of memory, and when any one of them is done, release it and take a new job. not pile the trash up and wait until it is unmanageable.

          • 1 month ago
            Anonymous

            Based C++ bro. After using C# for companies for many years, I want to return to C++ where I actually had control of things.

          • 1 month ago
            Anonymous

            I had a similar case building a query engine for big csv files, originally written in Go and then rewritten in C++. With garbage collection, a growable data structure like a vector would blow up the ram usage when indexing millions of rows because the old arrays would just hang around in memory for a while. Switching to C++ cut ram usage by over 10x.

          • 1 month ago
            Anonymous

            >With garbage collection, a growable data structure like a vector would blow up the ram usage when indexing millions of rows because the old arrays would just hang around in memory for a while.
            what the frick are you tards doing?
            >a growable data structure like a vector
            >when indexing millions of rows
            >the old arrays
            srsly wut

          • 1 month ago
            Anonymous

            You don't know how appending to vectors (or slices in go) works?

          • 1 month ago
            Anonymous

            i dont use shitlangs like go, and if indexing into an array causes the underlying array to be duplicated then i'm glad i dont
            point is, both you and the other pajeet suffer from skill issue. if you're going to work with a gc you need to learn how to work with or around it, not just build up gc pressure and start crying when it blows up in your face

          • 1 month ago
            Anonymous

            >point is, both you and the other pajeet suffer from skill issue. if you're going to work with a gc you need to learn how to work with or around it, not just build up gc pressure and start crying when it blows up in your face

            Is that so when the creator of C# says that if you want proper GC, that you should use unsafe block?

          • 1 month ago
            Anonymous

            i thought your problem was that the gc doesn't collect your garbage, not that it is being accidentally garbage-collected
            which is it?
            you pulled a random post from 24 fricking years ago that doesnt even support your argument

          • 1 month ago
            Anonymous

            >Is that so when the creator of C# says that if you want proper GC, that you should use unsafe block?
            Re-read your picrel. That's not even remotely what Hejlsberg is saying.

          • 1 month ago
            Anonymous

            I had assumed you could infer from my use case that I meant using vectors/slices for the purpose of indexing files. In my case, I was appending file positions to a vector, which in a garbage collected language causes it to periodically allocate a new array and copy the data to it, while the old one hangs around in the heap until the GC runs. That's an unavoidable problem when you don't control the garbage collection: growing an array like that will cause tons of dead arrays to stay in memory until the GC runs, taking up a ton of space.
            Cassandra has this problem too, which is why it's losing market share to Scylladb, which is 10x as efficient because it doesn't use garbage collection.

          • 1 month ago
            Anonymous

            >Cassandra has this problem too
            LMAX Disruptor somehow doesn't have this problem.

          • 1 month ago
            Anonymous

            I played around with Go the other day and used a channel to pool buffers. Take a buffer out when you need one, put it back when you're done, and you don't need to constantly allocate and initialize and free them.
            Those were fixed-size I/O buffers though, I don't know if it would scale to something complicated. And Go slices are very weird to begin with.

          • 1 month ago
            Anonymous

            So why did Google adopt Go again? Was it to make up for the incompetence of their engineers?

          • 1 month ago
            Anonymous

            >Was it to make up for the incompetence of their engineers?
            Well yeah they literally said so

          • 1 month ago
            Anonymous

            oh

          • 1 month ago
            Anonymous
          • 1 month ago
            Anonymous

            Jesus christ. I was just joking too. damn

          • 1 month ago
            Anonymous

            Go IS a brilliant language thoughever

          • 1 month ago
            Anonymous

            Assuming Go doesn't have a linked list in the standard library and you were too stupid to roll your own... Why didn't you just pre-allocate a large array directly instead of using lists? You could even do this in Python. This is optimization 101.

          • 1 month ago
            Anonymous

            To do that, you need to know how big it will be, which isn't possible when appending data from the file you're still parsing. There's no real performant GC-friendly solution I'm aware of for something that's growable and has random access unless you want some janky data structure similar to std::deque, which I didn't know about at the time.

          • 1 month ago
            Anonymous

            Use CGo, the best of both worlds. Or just use a hashmap. You may think it is wasteful, but hashmap is just linked list with buckets

          • 1 month ago
            Anonymous

            Assuming you're creating one array at a time and never growing them after you're doing parsing you could pre-allocate an enormous buffer and take slices from it for your individual arrays, one after the other. Only when you reach the end of the big buffer do you start a new one.

            [...]
            >You may think it is wasteful, but hashmap is just linked list with buckets
            Linked lists can be pretty wasteful. Modern hashtables don't use them though.

            CGo would work but would complicate cross-platform distribution. Hashmap has too much overhead for the high-performance application I was working on. Creating a huge buffer doesn't leave room for other parts of the program, which also need some ram. All are a cope for not using the best tool for the job, which for a high-performance query engine is a non-GC language.

            >Linked lists can be pretty wasteful. Modern hashtables don't use them though.
            what do they use then?
            [...]
            Also, C++ vector does the same thing. You are supposed to resize the array to a 1.5 * current, every time it goes out of capacity. append already does that so it is like a vector anyways

            The difference is how Go and C++ handle the old backing array when it needs to allocate a new one. C++ frees it immediately while Go lets them pile up until the GC runs.

          • 1 month ago
            Anonymous

            Arena?

          • 1 month ago
            Anonymous

            >Creating a huge buffer doesn't leave room for other parts of the program
            You don't have to overallocate very much because you can make a new buffer when the current one is full. I haven't actually used this technique but I think you could end up with less overhead than with a naïve vector solution (since whenever that grows it also preallocates space you may not use).

          • 1 month ago
            Anonymous

            Assuming you're creating one array at a time and never growing them after you're doing parsing you could pre-allocate an enormous buffer and take slices from it for your individual arrays, one after the other. Only when you reach the end of the big buffer do you start a new one.

            Use CGo, the best of both worlds. Or just use a hashmap. You may think it is wasteful, but hashmap is just linked list with buckets

            >You may think it is wasteful, but hashmap is just linked list with buckets
            Linked lists can be pretty wasteful. Modern hashtables don't use them though.

          • 1 month ago
            Anonymous

            >Linked lists can be pretty wasteful. Modern hashtables don't use them though.
            what do they use then?

            To do that, you need to know how big it will be, which isn't possible when appending data from the file you're still parsing. There's no real performant GC-friendly solution I'm aware of for something that's growable and has random access unless you want some janky data structure similar to std::deque, which I didn't know about at the time.

            Also, C++ vector does the same thing. You are supposed to resize the array to a 1.5 * current, every time it goes out of capacity. append already does that so it is like a vector anyways

          • 1 month ago
            Anonymous

            >what do they use then?
            Mostly linear probing.

          • 1 month ago
            Anonymous

            pretty sure you're just a bad programmer lmao

          • 1 month ago
            Anonymous

            Go has better GC

          • 1 month ago
            Anonymous

            Tell that to Slack.

        • 1 month ago
          Anonymous

          You have zero understanding of memory management and only parrot internet memes.

          Smart pointers generate boilerplate caused by having to handle exceptions (yes, even unique_ptr). shared_ptr uses reference counting, which is awful and can't handle cyclic references, which a proper tracing GC can. Let alone that neither allow memory compaction, which GC trivially allows.

          >always fails to do it in the right time. Or doesn't execute at all for a long time and then runs
          All forms of dynamic memory management have this problem, precisely because performance is unpredictable. Even a simple call to malloc(3) has unpredictable performance. If latency was that critical, you and your team were idiots for using dynamic allocation at all in that project (assuming it ever existed). This is why dynamic allocation is wholesale banned in MISRA, for instance.

          If your program has extremely tight timing constrains, GC is not appropriate, but neither is manual dynamic memory management. If it doesn't have such requirements, GC is better in every way.

          • 1 month ago
            Anonymous

            >Smart pointers generate boilerplate caused by having to handle exceptions (yes, even unique_ptr). shared_ptr uses reference counting, which is awful and can't handle cyclic references, which a proper tracing GC can. Let alone that neither allow memory compaction, which GC trivially allows.
            Rust doesn't have this problem. I think even C++'s smart pointers will be faster than having a global GC and have everything build around it. But yeah, managed languages are not made to be performance-critical, they are meant to make writing code easier and faster. If your program is IO-bound, the ~20% speedup won't matter.

          • 1 month ago
            Anonymous

            Rust has exceptions in the form of panics, though you can at least disable unwinding without changing all your error handling.
            Rust has problems with cyclic references in much the same way as C++ (and with the same solutions).

          • 1 month ago
            Anonymous

            >Rust has exceptions in the form of panics
            typical troony behavior
            41% of Rust exceptions end in program termination

          • 1 month ago
            Anonymous

            >Even a simple call to malloc(3) has unpredictable performance
            in theory yes.
            in practice on a system that haven't used up all RAM (thanks to GC), it's O(1) and instantaneous on Linux.

          • 1 month ago
            Anonymous

            What makes you think all C software is running on Linux, let alone any kernel?

          • 1 month ago
            Anonymous

            only morons use windows (a system designed literally for toy computers) for anything in real world.
            the entire industry runs Linux (VMs, supervisors, entire cloud computing).

          • 1 month ago
            Anonymous

            everything except for desktop

          • 1 month ago
            Anonymous

            only because of boomers
            desktop is almost dead anyway

  18. 1 month ago
    Anonymous

    posts like this really bring it into sharp perspective why C++ is the most exploited language on the planet. god damn what a fricking jumble of absolute shit that is.

    people in this thread can't even agree on what its doing or how it should be done, and its 20 lines. C++ needs to be regressed ten or fifteen major releases, or just put to death. its a liability

    • 1 month ago
      Anonymous

      what are you talking about, its simple code and the only argument is conceptual, not the syntax or functionality. are you slow?

      • 1 month ago
        Anonymous

        >its simple code and the only argument is conceptual,
        And yet it still has bugs in it lmao

    • 1 month ago
      Anonymous

      You just don't understand it's intent. C++ wasn't meant to be used as a whole but as a subset. The reason it has this many features is because nobody can decide what that subset would be. So the genius Bjarne just said "we will introduce everything, but you only pay for what you use". This has caused C++ to become the most used language for lower level development in the industry. It is a language that pleases everyone

      • 1 month ago
        Anonymous

        >we will introduce everything, but you only pay for what you use
        Code doesn't happen in vacuum. You pay for all these features and the cost isn't linear. You might always encounter some code using some combination of features you had no idea about.

        • 1 month ago
          Anonymous

          That is why companies use a subset. Didn't you read what I said

          • 1 month ago
            Anonymous

            You rarely limit yourself only to code written by single company. Unless you are a wage that literally doesn't do anything but work and you never use external code.

          • 1 month ago
            Anonymous

            C++ is meant for companies and businesses who already have C code, want more features, but cannot decide among themselves which ones.
            For individuals it is in 99% of cases satisfactory to use a GC language or even an interpreted one

          • 1 month ago
            Anonymous

            Nice cope.

      • 1 month ago
        Anonymous

        unfortunately intent does not equate to outcome. the outcome is that we now have a few dozen million jeet coders shitting out absolute trash every day in a language that is like some sort of rube goldberg machine meets mythological hydra meets swiss army knife.

        I concede freely that it may well be powerful, and in the hands of a competent developer could be useful, but unfortunately and regardless of intent it is by and large responsible for the most vulnerable and performance lacking code on the planet.

        • 1 month ago
          Anonymous

          This is what happens with a race to the bottom. jeet coders will make a mess of anything regardless of how idiot proof you try to make it.
          Rust is praised because it's a small subset of C++ with safe defaults and is currently only used by enthusiastic experts.
          If Rust ever becomes industry standard, you'll have jeets wrapping everything with unsafe.
          The only solution to jeet coders is higher wages and higher standard. Unfortunately, the industry makes more money by going the other way, but that's not C++'s fault.

          • 1 month ago
            Anonymous

            >Rust is praised because it's a small subset of C++
            Will it stay that way?

          • 1 month ago
            Anonymous

            No. When people start using these "simple" and "elegant" languages, they realize it lacks the features they need to do actual work. So eventually they get added or the language dies out as people move on.
            It's why all the C++ replacements (including cppfront) are a dead end. They're not cleaner, they're just less expressive.

          • 1 month ago
            Anonymous

            What features do you think Rust means?
            Not being bloated like C++ doesn't mean it's lacking. Have you forgotten just how unrealizably huge C++ is? 90% of it is either deprecated or not recommended to use.

          • 1 month ago
            Anonymous

            >Have you forgotten just how unrealizably huge C++ is? 90% of it is either deprecated or not recommended to use.
            Sounds to me like modern C++ is actually reasonably-sized.

          • 1 month ago
            Anonymous

            I like modern C++ - Rust as well.

          • 1 month ago
            Anonymous

            >What features do you think Rust means?
            Lacks*

            >Have you forgotten just how unrealizably huge C++ is? 90% of it is either deprecated or not recommended to use.
            Sounds to me like modern C++ is actually reasonably-sized.

            That's delusional.

          • 1 month ago
            Anonymous

            NTA but yeah. In contrast to C++, Rust isn't trying to be multi-paradigm. It has much clearer vision on what it aims to be.

          • 1 month ago
            Anonymous

            >Rust isn't trying to be multi-paradigm
            Black person what?
            >oop and functional
            >low level and webdev
            rust is just as much kitchen sink as c++, it's just a few decades behind

          • 1 month ago
            Anonymous

            Rust isn't OOP. It doesn't even have inheritance.
            Rust also isn't meant for webdev, it's systems programming language. If you want to do webdev, you use JS or Go.

          • 1 month ago
            Anonymous

            Rust already kinda fricked up with async.

          • 1 month ago
            Anonymous

            What is the problem with async

          • 1 month ago
            Anonymous

            It still feels like the same language as 1.0, just more refined. Modern Rust can do some things that were missing from 1.0, has a bigger standard library, refined a lot of the features that were already there. Going from 1.0 Rust to modern-looking Rust might be a matter of mechanically adding some syntactic sugar and helper functions. You could do a lot to modernize a library without breaking the public API. Most of the upcoming features I'm excited about (like specialization, any year now) might not require new syntax.
            Rust has a lot of complexity that you only need to care about when writing unsafe code or when working on the language itself. The average user doesn't need to know in which situations a temporary's lifetime is extended or what edge cases the orphan rule has, they just need to notice the compilation error and change their code. So it feels less complex than it actually is. (Until you get deep into the weeds and suddenly it doesn't.)

          • 1 month ago
            Anonymous

            Still just starting learning Rus, do you have big examples of what's changed so much? I want to make sure I'm not learning obsolete Rust.

          • 1 month ago
            Anonymous

            The Rust Programming Language, 2nd Edition
            came out Feb 2023 so its pretty recent

          • 1 month ago
            Anonymous

            NTA, non-lexical lifetimes are a big one for me. It didn't even changed anything in API, just allowed you to compile some programs that previously would confuse borrow checker.
            Generic associated types was also a big thing. It's a shame they came so late, some things in stdlib could benefit from it.

          • 1 month ago
            Anonymous

            There really isn't much that's big and hard to learn, except async, but async is its own thing that you have to learn separately regardless.
            cargo clippy can tip you off when there's a better way to do something, so make sure you use it. But otherwise you shouldn't worry about it.

          • 1 month ago
            Anonymous

            >It still feels like the same language as C++98, just more refined. Modern C++ can do some things that were missing from 1.0, has a bigger standard library, refined a lot of the features that were already there. Going from C++98 to modern-looking C++ might be a matter of mechanically adding some syntactic sugar and helper functions. You could do a lot to modernize a library without breaking the public API. Most of the upcoming features I'm excited about (like modules, any year now) might not require new syntax.
            >C++ has a lot of complexity that you only need to care about when writing unsafe code or when working on the language itself. The average user doesn't need to know in which situations a temporary's lifetime is extended or what edge cases the orphan rule has, they just need to notice the compilation error and change their code. So it feels less complex than it actually is. (Until you get deep into the weeds and suddenly it doesn't.)It still feels like the same language as C++98, just more refined. Modern C++ can do some things that were missing from 1.0, has a bigger standard library, refined a lot of the features that were already there. Going from C++98 to modern-looking C++ might be a matter of mechanically adding some syntactic sugar and helper functions. You could do a lot to modernize a library without breaking the public API. Most of the upcoming features I'm excited about (like modules, any year now) might not require new syntax.
            >C++ has a lot of complexity that you only need to care about when writing unsafe code or when working on the language itself. The average user doesn't need to know in which situations a temporary's lifetime is extended or what edge cases the orphan rule has, they just need to notice the compilation error and change their code. So it feels less complex than it actually is. (Until you get deep into the weeds and suddenly it doesn't.)

          • 1 month ago
            Anonymous

            You can swap in different words but that doesn't make them true. C++98 has new and delete, modern C++ has smart pointers, but Rust had smart pointers from the start. String views are new in C++ but Rust has always had them. If you frick up with temporaries in C++ you don't get a compilation error, you get UB.

          • 1 month ago
            Anonymous

            >but Rust has always had them
            Yeah, that's what happens when you show up 2 decades later and can benefit from all the hindsight.

          • 1 month ago
            Anonymous

            Yes, exactly. Do we disagree about anything?

          • 1 month ago
            Anonymous

            Is this what C++ programmers believe? Kek

          • 1 month ago
            Anonymous

            >It still feels like the same language as C++98
            lol

            Is this what C++ programmers believe? Kek

            Bad C++ programmers

        • 1 month ago
          Anonymous

          >most vulnerable
          It's mostly C.

      • 1 month ago
        Anonymous

        >C++ wasn't meant to be used as a whole but as a subset.
        Source: my ass.

        • 1 month ago
          Anonymous

          I do remember a story about an intern at Bell Labs who had an assignment to create some library in C++ and he couldn't make his design work, so his advisor told him go up two floors, that's where the C++ design team works, and he went upstairs and explained his problem and they said oh yeah those features don't work together, you should use either one or the other

          >However, once you have objects with non-trivial lifetimes, GC is better.
          Wrong.
          Smart Pointers are the answer.
          GC is shit. It's a process that fires randomly and always fails to do it in the right time. Or doesn't execute at all for a long time and then runs and takes up all resources for an hour (real life problem we had). GC is... garbage.

          How about refcounting baked into the language/runtime a la Swift?

          • 1 month ago
            Anonymous

            >How about refcounting baked into the language/runtime a la Swift?
            NTA, and I do not know how does it work in Swift, but 90% of time you do not need a shared pointer, counting references is pointless in this scenario. It gets especially bad if your language does not differentiate between atomic and non-atomic reference counting like in case of C++.

          • 1 month ago
            Anonymous

            >refcounting baked into the language/runtime a la Swift?
            baked into = slow
            because in 90% of cases you don't need a smart pointer (or a pointer at all). only when something leaves the scope and is stored somewhere with undefined lifetime.

  19. 1 month ago
    Anonymous

    And ciniles claim Rust is ugly.
    Lmao, kek even.

    • 1 month ago
      Anonymous

      Somehow Rust manages to be worse.

      • 1 month ago
        Anonymous

        I beg to differ.

        • 1 month ago
          Anonymous

          How is this better than C++

          • 1 month ago
            Anonymous

            homie it IS C++

          • 1 month ago
            Anonymous

            Well it looked like rust from the way it was written. You can tell it was a rustacean who wrote this

          • 1 month ago
            Anonymous

            I had no idea rustafarians wrote GCC.

          • 1 month ago
            Anonymous

            Isn't gcc written in c

          • 1 month ago
            Anonymous

            GCC uses many languages. C++ stdlib will be obviously written in C++.

          • 1 month ago
            Anonymous

            I mean if they didn't use so many underscores and gave classes proper names it wouldn't be bad

        • 1 month ago
          Anonymous

          How can they make a code so ugly

          • 1 month ago
            Anonymous

            Part of it is the identifier naming rules. Only identifiers starting with double underscores or an underscore followed by a capital letter are reserved by the language. They use those internally so it can't clash with use code. The other part is the absolutely moronic code formatting guidelines they follow for some reason.

        • 1 month ago
          Anonymous

          >underscores as namestarters
          Why. __The_shit.__isnt_(std::ack::__great_).

  20. 1 month ago
    Anonymous

    yeah uh if you run out of memory that's a YOU problem.

  21. 1 month ago
    Anonymous

    all C++ users should get AIDS

  22. 1 month ago
    Anonymous

    What's the best books to learn c++ for a brainlet?

    • 1 month ago
      Anonymous

      Anyone got an answer to this? Another tard here also interested in c++

    • 1 month ago
      Anonymous

      Anyone got an answer to this? Another tard here also interested in c++

      Disregard books, just go do learncpp.com

  23. 1 month ago
    Anonymous

    How do I escape Java hell and pivot into a C++ job?

  24. 1 month ago
    bruce3434

    >has RAII
    >implements defer

  25. 1 month ago
    Anonymous

    this will fail on exception

    • 1 month ago
      Anonymous

      don't use them

      • 1 month ago
        Anonymous

        not a option with std

        • 1 month ago
          Anonymous

          dont use std

  26. 1 month ago
    Anonymous

    >it's a bad thing when D can be anything
    >a good thing when C++ can
    hmmm

  27. 1 month ago
    Anonymous

    i spent 15 minutes reading all the code posted here

    i dont understand the hieroglyps in half of it... maybe ill just stick to good old python

    • 1 month ago
      Anonymous

      Hehehe...
      from __future__ import annotations

      import ctypes, dataclasses, os, typing

      type Callback = typing.Callable[[], object]

      @dataclasses.dataclass
      class Deferrer:
      callbacks: list[Callback] = dataclasses.field(default_factory=list)

      def __call__(self, callback: Callback):
      self.callbacks.append(callback)

      def __enter__(self) -> Deferrer:
      return self

      def __exit__(self, *_):
      exceptions = []
      for callback in reversed(self.callbacks):
      try:
      callback()
      except BaseException as e:
      exceptions.append(e)
      if len(exceptions) == 1:
      raise exceptions[0]
      elif exceptions:
      raise ExceptionGroup("multiple defer failures", exceptions)

      with Deferrer() as defer:
      defer(lambda: print("Goodbye"))
      print("Hello")

      libc = ctypes.CDLL('libc.so.6')
      libc.__errno_location.restype = ctypes.POINTER(ctypes.c_int)
      libc.fopen.restype = ctypes.c_void_p
      libc.fclose.argtypes = [ctypes.c_void_p]

      fp = libc.fopen(b"test.txt", b"rb")
      if fp is None:
      errno = libc.__errno_location().contents.value
      raise OSError(errno, os.strerror(errno))
      defer(lambda: libc.fclose(fp))

      • 1 month ago
        Anonymous

        or just do this?
        with open("x.txt", "wr"):
        # Do something
        # file automatically closed

        • 1 month ago
          Anonymous

          >automagical management of data access
          >wr
          >w
          Tell me how are you going to do this multithreaded.

          • 1 month ago
            Anonymous

            just run multiple scripts on different cores?

          • 1 month ago
            Anonymous

            doesn't matter because python does not support true multithreading anyway (every variable has a global mutex lock)

          • 1 month ago
            Anonymous

            multithread file writes are somewhat dangerous but managed by filesystem (at least on real operating systems)
            in Linux you are even guaranteed the order and completeness of lines appended to a file concurrently (no longer than 4kb AFAIR)

          • 1 month ago
            Anonymous

            As long as different threads don't touch the same handle and preferably not the same file you're good. That example is pretty explicit.

            doesn't matter because python does not support true multithreading anyway (every variable has a global mutex lock)

            The GIL prevents data races but doesn't do much to stop other race conditions. Threads can be interrupted at almost any time.

    • 1 month ago
      Anonymous

      You should feel right at home since Python borrowed the double underscore convention.

      • 1 month ago
        Anonymous

        what language does the double underscore convention come from. im sure i saw it in poplog (prolog). its power.

    • 1 month ago
      Anonymous

      I understand it but I could not come up with it so we are in the same boat

  28. 1 month ago
    Anonymous

    When using Win32's SetProp && GetProp
    Why am I getting garbage values when I attempt a GetProp outside of the scope i used SetProp in?
    Doesn't matter if I use the hwnd or GetActiveWindow()

  29. 1 month ago
    Anonymous

    std::function is incredibly bloated and should never be used for any purpose. Also, you don't need std::function to implement defer. Also, your defer is horrible to use. Its much better if you wrap it in a macro.

    • 1 month ago
      Anonymous

      >std::function is incredibly bloated and should never be used for any purpose
      Is there any reason they made it this way? Why add an abstraction if it's that costly?

      • 1 month ago
        Anonymous

        To be fair you're paying for what you use. Closures require storage for their captures; std::function can contain any function or function object with a given signature; thus std::function must(*) use heap allocation if there are captures. If you don't need captures, then use a normal function pointer.

        * I don't know how std::function is implemented, maybe it has some kind of SBO like std::string, but I've never heard of implementations doing this. You could probably come up with a specialized version of std::function that takes a Max_Bytes parameter and stack-allocates that much storage for captures, but that's obviously not a general case solution.

    • 1 month ago
      Anonymous

      >std::function is incredibly bloated and should never be used for any purpose.
      What should you do instead in C++ if you need that degree of polymorphism?

      • 1 month ago
        Anonymous

        Rethink your design.

        • 1 month ago
          Anonymous

          Because it's inherently bad or because std::function is bad or because there's not even a theoretical acceptable way to implement it?
          I don't know the details of std::function. In Rust you'd use a trait object, which is a fat pointer with one half pointing to a (static) vtable and one half pointing to the closure data, if any. The vtable contains the function and a destructor for the data. (The fat pointer itself can be any pointer type, including references and smart pointers.) Obviously if you can get away with using a bare function pointer you should do that instead but it doesn't feel terribly egregious.
          Is std::function like that or is it doing other bullshit? Or is the only issue that it forces heap allocation?

          Personally, I would just use normal functions for callbacks.

          What if the caller needs to associate data with callbacks? I've used C APIs with void pointer arguments but that doesn't seem like the C++ way. Closures are nice.

          • 1 month ago
            Anonymous

            > doesn't seem like the C++ way
            Since most aspects of C++ are terrible, the C++ way is not something I hold with much regard.

      • 1 month ago
        Anonymous

        Personally, I would just use normal functions for callbacks.

      • 1 month ago
        Anonymous

        Because it's inherently bad or because std::function is bad or because there's not even a theoretical acceptable way to implement it?
        I don't know the details of std::function. In Rust you'd use a trait object, which is a fat pointer with one half pointing to a (static) vtable and one half pointing to the closure data, if any. The vtable contains the function and a destructor for the data. (The fat pointer itself can be any pointer type, including references and smart pointers.) Obviously if you can get away with using a bare function pointer you should do that instead but it doesn't feel terribly egregious.
        Is std::function like that or is it doing other bullshit? Or is the only issue that it forces heap allocation?

        [...]
        What if the caller needs to associate data with callbacks? I've used C APIs with void pointer arguments but that doesn't seem like the C++ way. Closures are nice.

        Well, which degree of polymorphism exactly? If it's for OP's case, you just need static polymorphism, so replace the std::function with a template (with an "invocable" requirement). That way it can accept a lambda, a std function or a regular function.

  30. 1 month ago
    Anonymous

    >10 lines in python
    >130 in C++
    don't have time for that bullshit, you fricking hobbyists

  31. 1 month ago
    Anonymous

    You can also make errdefer by using uncaught_exception in the destructor: https://en.cppreference.com/w/cpp/error/uncaught_exception

  32. 1 month ago
    Anonymous

    Resource Acquisition is Irreversible
    RAII
    The moment you ask the OS for anything you are in the wild jungle of footguns

    • 1 month ago
      Anonymous

      however if it is Linux, you can sleep well. it just works.

  33. 1 month ago
    Anonymous

    What are people using on Linux/macOS to develop C++ in? Is VSCode good enough? My goal is to overconfidently jump into a codebase and hack on a feature everyone wants but is too lazy to plan out and implement.

    • 1 month ago
      Anonymous

      vim

      • 1 month ago
        Anonymous

        I use nvim whenever I'm not in an IDE these days so that would be ideal. Hopefully C++ is LSP friendly. Never really looked into it

    • 1 month ago
      Anonymous

      My work involves a lot of chromium code which is a huge c++ codebase and neovim with clangd via lsp-zero handles it just fine.

  34. 1 month ago
    Anonymous

    Why would I use C++ when C exists.

  35. 1 month ago
    Anonymous

    o7

Your email address will not be published. Required fields are marked *