|
OddObserver posted:That's sort of a problem, isn't it? Like if you actually care about safety and are going to put in an effort to switch to a C++ reskin suddenly going all the way to something like Rust starts being attractive? I think it's an easier sell than learning a completely new language and environment, and dealing with all the interop. Not today, obviously, but in the next 5 years or so if the idea gets refined a bit.
|
# ? Nov 16, 2022 20:14 |
|
|
# ? Jun 3, 2024 10:14 |
|
fortunately I've been able to avoid this issue of passing unique pointers so far because every time I've wanted to construct a member outside of the object, it's because I want it to be usable in multiple places, so shared_ptr is correct for reasons entirely unrelated to rvalue nonsense
|
# ? Nov 16, 2022 20:24 |
|
Xerophyte posted:My concern is that you said "I want to pass in a ready-to-go std::istream, and I do want ownership of it to move to the consumer." istream has disabled moves specifically to ensure it is not possible to do that, because it is not in general a safe operation. An istream may be a system resource that cannot be locally owned. Moving is only enabled for classes derived from istream that represent something that can be owned and have its ownership transferred, notably ifstreams. When I came into this, the proof of concept was plain std::ifstream only, no polymorphism. The whole world handles these files gzip compressed, and my lab uses a lot of zstd compression, so I used boost::iostreams::filtering_stream, but wanted to be able to leave parts of the application untouched and still using plain ifstreams. boost filtering_streams are istreams, but not ifstreams, and all that I need from any of them is the istream interface. You explained pretty clearly why I can't assume every istream is move-able, and I guess I should just change all of these to boost filtering_streams instead. I just came in with Java brain and saw "We are only using these as istream? Let's just type the whole thing std::istream." They're all only std::ifstream or boost::iostreams::filtering_istreams anyway. Side note: Is boost::iostreams still the right thing to be reaching for for basic compression / decompression of gzip and zstd? Bonus points for something that uses Intel isa-l instead of zlib, as it's night-and-day faster and we use igzip. I've been thinking about writing a boost filter that links against isa-l myself, but my group tends to just use zstd instead. I feel like other users that are using gzip would sure appreciate it, though. Xarn posted:Calling sink1 will not always zero-out the passed pointer, because std::unique_ptr<Data>&& is a reference and thus the caller's unique ptr instance will only be modified after the coinflip. This is different from sink2 where caller's pointer is always moved-out, because it has to be moved into the function before the coinflip happens. Oh wow, I would never want a pointer to not be moved into the function when calling it with std::move, so you've convinced me that value semantics are safer for this situation. I can already think of a handful of exciting ways that && and not moving it could explode spectacularly. cheetah7071 posted:I'll put up with all the C++ nonsense just to have namespaces and std::vector Tired: C-with-classes style code Wired: C with vector
|
# ? Nov 16, 2022 20:34 |
|
Twerk from Home posted:When I came into this, the proof of concept was plain std::ifstream only, no polymorphism. The whole world handles these files gzip compressed, and my lab uses a lot of zstd compression, so I used boost::iostreams::filtering_stream, but wanted to be able to leave parts of the application untouched and still using plain ifstreams. boost filtering_streams are istreams, but not ifstreams, and all that I need from any of them is the istream interface. stb has dynamic arrays https://nothings.org/stb_ds/
|
# ? Nov 16, 2022 21:25 |
|
Sweeper posted:If you are new to cpp bookmark https://www.cppreference.com or add a quick search so you can type “cpp std::map” into url bar thing to lookup docs. I look things up all the time because c++ is inconsistent and many apis work in ways which make sense in the context of the standard, but aren’t intuitive. It’s a great site, bless the maintainers. Yes. Our course even had some homework regarding using CPPref. I just forget to do this often enough. Most of the Book was already presented ready for us. File reading, commandline handling etc. Only the implementation of Book classes methods was left for us. They gave us a ready struct we need to use for the chapters. I managed to do this not quite yet finished or even tested implementation yesterday: https://pastebin.com/uPDac0fA At least some kind of recursion and shared pointers feel a lot easier to use when you can do whatever by yourself, and are not constrained too much by the strict limits set by coursework.
|
# ? Nov 17, 2022 14:41 |
|
Ihmemies posted:Most of the Book was already presented ready for us. File reading, commandline handling etc. Only the implementation of Book classes methods was left for us.
|
# ? Nov 17, 2022 14:47 |
|
quote:std::shared_ptr<Chapter> parentChapter_ = nullptr; ...I have questions.
|
# ? Nov 17, 2022 15:03 |
|
An N-ary tree with cyclic references, what could possibly go wrong.
|
# ? Nov 17, 2022 16:00 |
|
roomforthetuna posted:Is that Params monstrosity part of what they give you? Jesus. Yes. Function parameters are given inside that params variable. The Chapter struct was given to us. Initially they were regular pointers like this: code:
code:
code:
code:
Xarn posted:An N-ary tree with cyclic references, what could possibly go wrong. I am glad I have no idea, because I don't know what is an N-ary tree, or what are cycling references, or even what can possibly go wrong Ihmemies fucked around with this message at 21:22 on Nov 17, 2022 |
# ? Nov 17, 2022 21:15 |
|
the distinction between unique_ptr and shared_ptr is: do I want this object to always be deleted when the pointer goes out of scope? if yes, use unique_ptr. If you need it to stick around because other parts of the code are potentially still using it, use shared_ptr. I don't know which you need for this specific task, but the distinction is pretty simple weak_ptr is a kind of weirder one and I think if you're struggling with the concept of pointers to begin with, you probably won't be using it at all
|
# ? Nov 17, 2022 21:35 |
|
cheetah7071 posted:the distinction between unique_ptr and shared_ptr is: I look at them in terms of ownership. Who "owns" this pointer? - One object at a time - unique_ptr - Everybody and their grandmother? - shared_ptr - weak_pr for when I need to know that my object is dead already by the time a callback is called. And for that I need shared_ptr. And, of course, when the object needs to keep itself alive, then also shared_ptr.
|
# ? Nov 17, 2022 21:39 |
|
Thanks! One reason also was (now when I'm re-reading this week's material) that they said "On this course, we will only get to know the type shared_ptr.". So it should be good enough for now. I guess I'd have to manuallydo a bunch of deleting in class destructor and maybe methods if I used regular pointers instead, and analyze with Valgrind if I succeed in that task or not.
|
# ? Nov 17, 2022 21:44 |
|
Of more immediate significance: if your shared_ptr's form a cycle, they'll never get cleaned up. (I apologize if my earlier comment was too snarky, I thought it was the code that you were provided...) Edit: oh boy, they have you using shared_ptr and are not explaining cycles? Let's see, the arrow here are shared_ptr's, and I'll represent the Chapter objects with their names: pre:Introduction to the Basic Concepts ( 2 ) | /\ | | subchapters_[0] parentChapter_ | | | | \/ | Definitions ------------------------ The way shared_ptr works is basically by freeing memory when the number of incoming arrows is zero. And here, you'll always have incoming arrows, as parent points to child and child to parent. OddObserver fucked around with this message at 21:52 on Nov 17, 2022 |
# ? Nov 17, 2022 21:45 |
|
OddObserver posted:Of more immediate significance: if your shared_ptr's form a cycle, they'll never get cleaned up. So if the program quits they stay in memory? Or those things stay in memory until the program closes? Is it bad if they stay in memory while the program is running? I quickly read about trees and this page suggested to do first child/next sibling data structure: https://www.geeksforgeeks.org/generic-treesn-array-trees/ I guess that is impossible at this situation but from looking at it it looks more efficient? Maybe I should replace the smart pointers with regular pointers and uhh do some manual deletion... Or maybe uhhhh make the uhh parent as a regular pointer and delete those in class destructor? Ihmemies fucked around with this message at 21:54 on Nov 17, 2022 |
# ? Nov 17, 2022 21:48 |
|
Ihmemies posted:So if the program quits they stay in memory? What kind of sense that makes? No, if you close the process, it will go away. However, you will leak memory while it is running, as in any cycles of shared_ptrs pointing at each other will keep the pointed objects alive as long as the process runs. You have to manually break cycles with weak_ptrs somewhere in the cycle, which will not keep the pointed-at object around.
|
# ? Nov 17, 2022 21:52 |
|
If you're used to python, shared_ptr should be pretty intuitive to you because it's how python objects work. An object might exist in multiple places (it might be a member of multiple objects, it might be declared in one function, then used an argument in another, etc). When all of those places pass out of scope, the garbage collector cleans it up--or, in C++ terms, the object's destructor is called Handling all of that is a bit slow though so unique_ptr exists for the case where you can guarantee that the object only exists in one place. It's a bit faster, and can prevent bugs in scenarios where you accidentally put an object in two places at once without intending to, because that code won't even compile The circular references thing exists in python as well, though I think more modern versions of it have a complicated garbage collector that tries to detect them? It's been a while since I used python so I'm not sure. It occurs when you have a scenario like, object A contains object B as a member, and object B contains object A as a member. Because neither of them have 0 references, neither can be destroyed. Shared_ptr has the same risks if you aren't careful
|
# ? Nov 17, 2022 22:01 |
|
Well all the the chapter data is needed as long as the created book class object? instance? whatever it's called is alive, since the data is read only once from file. So I guess it's ok that the shared pointers keep existing in memory, as long as the instance is alive and needed. In class destructor, do I need to iterate through the all the chapters and manually delete the pointers, or change parentchapter type to weak pointer or something? Seems they explained the cycles (I looked) but I forgot already about it. My memory is very bad in general. Or should I change the parentchapters to unique pointers or something.. hmm.. I need to study more.
|
# ? Nov 17, 2022 22:06 |
|
You almost never need to manually write a destructor. The default one covers you 99% of the time. The biggest exceptions in aware of are if you need to do something other than destroy objects for some reason, or if you're interfacing with C code and thus working with objects that don't have destructors
|
# ? Nov 17, 2022 22:09 |
|
cheetah7071 posted:You almost never need to manually write a destructor. The default one covers you 99% of the time. The biggest exceptions in aware of are if you need to do something other than destroy objects for some reason, or if you're interfacing with C code and thus working with objects that don't have destructors But in this case I need to clearly do something else than I'm doing, because of that circular shared ptr thing. I just need to figure out what would work better.
|
# ? Nov 17, 2022 22:10 |
|
If you're writing a complicated destructor, that's still usually a sign that something has gone wrong In case it helps, here's the use case for weak_ptr: weak_ptr points to an object that used to exist, and may or may not still exist. A weak_ptr existing won't prevent an object from destructing the way a unique_ptr or shared_ptr will. In order to use a weak_ptr, you ask it if the object it points to still exists--if it doesn't, you do some fallback case. If it does, you get a shared_ptr which you can use temporarily, to lock in the object continuing to exist for a little while. When you're done with it, you just let the shared_ptr go out of scope and the weak_ptr will stick around, pointing to an object which may or may not exist
|
# ? Nov 17, 2022 22:23 |
|
Ihmemies posted:But in this case I need to clearly do something else than I'm doing, because of that circular shared ptr thing. I just need to figure out what would work better. If you were trying to actually write good code, the *general* rule is use unique_ptr unless you have a good reason to use shared_ptr and you know why. In this case you have a vector of things that clearly owns them; you can use bare pointers or references to navigate between them, then they get destroyed when that vector goes away, which is exactly what you want to happen.
|
# ? Nov 18, 2022 00:23 |
|
Course said don't mix regular and smart pointers. So I won't be mixing them. Since I don't understand at all the differences between smart pointers, and I understand even less about how to manually release memory of regular pointers when they are not needed anymore, I'll just keep using the shared pointers. The user can buy more RAM if he runs out of it because of shared pointer linking. I don't give a drat.
|
# ? Nov 18, 2022 10:53 |
|
roomforthetuna posted:If you were trying to actually write good code, the *general* rule is use unique_ptr unless you have a good reason to use shared_ptr and you know why. In this case you have a vector of things that clearly owns them; you can use bare pointers or references to navigate between them, then they get destroyed when that vector goes away, which is exactly what you want to happen. This is the correct approach Ihmemies posted:Course said don't mix regular and smart pointers. So I won't be mixing them. Since I don't understand at all the differences between smart pointers, and I understand even less about how to manually release memory of regular pointers when they are not needed anymore, I'll just keep using the shared pointers. The user can buy more RAM if he runs out of it because of shared pointer linking. I don't give a drat. You should not mix regular and smart pointers for ownership. Mixing them in your code is pretty standard, as you use plain pointers for things that do not participate in ownership, but want to have potentially nullable look at something. references for things that do not participate in ownership (or will make a copy), but do not accept nulls, and so on.
|
# ? Nov 18, 2022 11:00 |
|
Sorry. This will use shared pointers for everything. I don't have the time or capacity to learn to do it any other way at this stage.
|
# ? Nov 18, 2022 13:15 |
For a short running program, leaking memory is fine anyway. Memory leaks matter in long running programs like server processes and GUI programs, but if you just load some data, process a bit, then exit, then cleaning up your own memory is likely to be a waste of effort. See also the anecdote about the control program for a ballistic missile that was found to have a memory leak. No reason to fix it when the missile would explode before the memory ran out.
|
|
# ? Nov 18, 2022 13:20 |
|
Ihmemies posted:Course said don't mix regular and smart pointers. So I won't be mixing them.
|
# ? Nov 18, 2022 13:39 |
|
Ideally I'd learn more about different types of smart pointers if I had the possibility to do a project from the ground up. Now I don't understand enough about my program to refactor it again to work with different kind of pointers. I mean I got it to work "perfectly" as in the code gives expected printouts and it passes the tests. Now the data sits in memory until program is closed, because of the linked shared pointers. Anyways, uhh, maybe I could at least find a way to lessen the repetition. It has so many methods which have nearly the same contents, just copy pasted to other methods. Like printLongestInHierarchy vs printShortestInHierarchy, printParentsN, printSubchaptersN etc. I have to figure some way to remove repetitive code, since it's penalized in grading...
|
# ? Nov 18, 2022 15:01 |
|
Ihmemies posted:Ideally I'd learn more about different types of smart pointers if I had the possibility to do a project from the ground up. Smart pointers are just objects with pointer semantics. The common uses of them are for garbage collecting (e.g. refcounted pointers) and managing ownership. They're also useful when you have unusual memory layouts. E.g. a chunk of memory available through some bank switching mechanism. These get exposed via a series of methods. Often you'll track the bank, offset in that bank, and possibly length held. Smart pointers allow you to use this memory with a uniform syntax. Otherwise, to use your existing methods that take a reference to something you would need to pull that thing into a temp, call the method on the address of your temp, then write back if it was changed. Supporting uniform memory access for banked memory via smart pointers is the feature that's made me most strongly consider moving to C++ from C. Haven't managed to convince myself it's worth it yet.
|
# ? Nov 18, 2022 16:58 |
|
As much as I despise C, I would encourage you to first move to a platform that doesn't require banked memory. (Though I suppose I may need to congratulate you on working on something that's high volume enough to justify such a platform?)
|
# ? Nov 18, 2022 17:03 |
|
OddObserver posted:As much as I despise C, I would encourage you to first move to a platform that doesn't require banked memory. (Though I suppose I may need to congratulate you on working on something that's high volume enough to justify such a platform?) Uhh.. it's a game for the loving wonderswan. I can't exactly get more main memory, but it has loads of SRAM available on the cart. And if I'm deranged enough to have started this project, recommending reasonable projects on reasonable platforms isn't going to fix my problem. If I commercialize, I'd need to design and manufacture custom carts. I have plans for this, but haven't pulled the trigger on purchasing any of the stuff I'd need for it. If I follow through on manufacturing, i don't expect I'd get more than 100 sales (probably more like.. 5-10) for the WS/WSC cart. Though I have ports running on modern Windows, modern Mac, and Linux (as well as SVGA DOS, CGA dos, Gameboy Advance, Sega Saturn, and a few other platforms I'm forgetting about presently). You can congratulate me on my career shift into management, which has freed up time and energy for dumb projects in my free time.
|
# ? Nov 18, 2022 17:16 |
|
Oh, I was guessing it was some sort of embedded thing where you had to save 50 cents on a chip so ended up with weirdly retro capabilities, rather than were doing the fun retro stuff....
|
# ? Nov 18, 2022 17:24 |
|
OddObserver posted:Oh, I was guessing it was some sort of embedded thing where you had to save 50 cents on a chip so ended up with weirdly retro capabilities, rather than were doing the fun retro stuff.... Don't get me wrong, I'd love doing the sad retro stuff too, but day job is service games which doesn't make me a strong candidate for cost optimization in the teledildonics industry or w/e still employs embedded people.
|
# ? Nov 18, 2022 17:29 |
|
I've been migrating my project to using conan and it went 90% well but Boost of all things is loving up. I figure Boost is big enough that someone here probably knows the intricacies of why things are going wrong. Here's my entire conanfile.txt: quote:[requires] And here's the part of my cmakelists.txt that's relevant to boost: quote:find_package(Boost REQUIRED) both conan and cmake run fine without warnings or errors. Checking the linker settings in Visual Studio, the only boost thing in my list of lib files is C:\.conan\9cebf8\1\lib\libboost_program_options.lib, which is a file that exists. When I try to build, however, I get this linker error: "LNK1104 cannot open file 'boost_program_options-vc143-mt-x64-1_80.lib'" Normally I'd just assume that something in my cmake was generating incorrect settings, but like...I'm not even trying to link to that file. I recognize that filename, it's produced by building boost with some settings (and other settings give the filename that actually occurs in my linker settings). I'm pulling my hair out here trying to figure out why I'm getting a linker error for a file that I'm not even linking to. The same thing happens in my tests I have no idea if this is a visual studio bug, an issue with my cmake file or somehow using conan wrong
|
# ? Nov 18, 2022 20:44 |
|
This week's C++ task said posted:Many of the functions do similar things. You should think carefully, which utility functions to implement in order to avoid repeating code. So. We have stuff like:
And I have been at the task, combining 2 methods to 1, avoiding repeating code, with ternary operators! C++ code:
C++ code:
C++ code:
I have this like 7 times in different methods, still researching a way to combine them too. Maybe all the methods should call an utility method, which does this, and then that utility method calls the correct method? C++ code:
E: nvm the comments in files forbid us from editing them: Student's don't touch this file. This week's C++ task said posted:You need not modify the ready-made functions. It is not necessary to understand the functionality of the modules Utils or Cli. However, since the topic of the round is modularity, this is a good example to be explored as a whole. Ihmemies fucked around with this message at 20:56 on Nov 18, 2022 |
# ? Nov 18, 2022 20:49 |
|
mobby_6kl posted:I just created a new programming project for myself by being an idiot. I basically bricked the touchscreen on my laptop by trying to update it, because the response to the pen wasn't good and that was supposed to help. Unfortunately a) it turned out to be the wrong update, and it didn't check for compatibility, b) it actually flashed some settings into the controller so no amount of driver reinstalls will help. The sample app doesn't seem to the the right thing, it's from loving 1998 and not related to HID over I2C, I guess the "Recommended content" list as automatically generated by AI. The actual page has no information about how to actually write anything for the driver. Another option I thought is to reverse-engineer the app I have for updating the firmware. I found a thing called "Cutter" which seems to have a decompiler which is great because I'm poo poo at interpreting anything but basic asm. leper khan posted:Yes. Return to C You can always just implement any features you miss from C++ yourself
|
# ? Nov 18, 2022 23:19 |
|
mobby_6kl posted:You can always just implement any features you miss from C++ yourself Per my previous post, everything but operator overloads, yes.
|
# ? Nov 18, 2022 23:48 |
|
cheetah7071 posted:snip while I am still deeply curious how I managed to get a situation where the linker was complaining about being unable to find a file I wasn't trying to link to, I switched to vcpkg and everything works now so good riddance, I guess
|
# ? Nov 19, 2022 00:13 |
|
leper khan posted:Per my previous post, everything but operator overloads, yes. You have __Generic though.
|
# ? Nov 19, 2022 15:59 |
|
I never really saw the point with _Generic. Don't you have to write a bunch of functions that handle each type? If a C programmer wants generics, they would just write one macro function that handles everything.
|
# ? Nov 20, 2022 01:00 |
|
|
# ? Jun 3, 2024 10:14 |
|
The point is that you get to specialize the implementation for specific types, instead of having to write convoluted code that will inherently compile and work correctly for every type you could possibly pass in. Having a library of utility macro functions that work correctly regardless of the type of the expression you pass in is extremely useful for the times when you do want to write "one macro function that handles everything"!
|
# ? Nov 20, 2022 01:14 |