9 ms·
So in the first question, they test to make sure the candidate knows the minutia that std::unique_ptr<> has no copy constructor. And in the followup, they assu
by cjensen 8y ago
So in the first question, they test to make sure the candidate knows the minutia that std::unique_ptr<> has no copy constructor.
And in the followup, they assume the candidate will just assume that "SearchQuery", whose header is not shown, will have a copy constructor.
Just no.
- slavik81 8y agoI looked at that first one and didn't realize it wouldn't compile simply because I would never write something like that anyways. That function should just take an int&. However, understanding that SearchQuery is broken is pretty important. Breaking the Rule-of-3 is probably the #1 mistake made by junior C++ developers trying to write object-oriented code, and the consequences are pretty nasty. You'll get corruption and crashes from use-after-free and double-free errors and nothing will make sense because the problem will move around as you create temporary copies while trying to debug. That being said, I wasn't familiar with that sort of stuff when I was first hired as a C++ developer. I was very fortunate to start my career with a company that was willing to hire people and train them.
- AstralStorm 8y agoIt is usually called rule of five, 3 is half of it and makes people sometimes forget to write move assignment. I'm pretty sure business do not like to actually train people nowadays. :)
- slavik81 8y agoI originally wrote "Rule-of-Three / Rule-of-Five / Rule-of-Zero" but regrettably, I cut it for brevity.
- jemfinch 8y agoBy volume of content it's "usually" called the rule of 3, because the rule of 5 didn't exist until C++11, and most of the C++ content was written before moving was a thing. It's now called the rule of 5.
- lasagnaphil 8y agoRight now one of the major gripes I have about Modern C++ is RAII / Rule-of-five. After going through all of this stuff I felt it brought too much complexity for what it tried to accomplish... RAII basically assumes that your objects are always going to be in the init-use-free pattern (you read a file, you use it, and close it after you’re finished) In reality not all things work this way, as objects have various different states according to their state machines and will use and free resources depending on that state. But in Modern C++ you’re forced to think only in the on/off paradigm, which results in lots of small unnecessary classes with their own on/off state. (If you try graphics programming you’ll understand right away...) Now when you add rule-of-five this becomes a monstrosity to handle, as you have to ensure about memory copying/moving for every little RAII class you make. So why not let normal assignment be shallow copy by default, but have an explicit copy() method? Why is everything so implicit in Modern C++ where you can’t assure that by simply looking at a = b you can’t tell how memory is allocated/freed... Nowadays I have lost hope in Modern C++ and are looking for alternatives: Rust (complex but at least memory safe) Orthodox C++ (not memory safe but at least sane for graphics/game programming), or Jai/Zig/other experimental lnguages (which claim to be a better C)
- colanderman 8y agoAssignment is supposed to perform a deep copy because otherwise you need to be aware of the implementation of the object you are copying, which may or may not allocate data on the heap. By forcing a deep copy, all assignments have identical semantics – you obtain a new, independent copy of the resource. You could say, "well, developers can just adopt a uniform semantics for what parts of objects are considered 'shallow' vs. 'deep'", but now the compiler can generate correct default copy operations in many fewer cases, since the rule is arbitrary vs. simply "copy everything".
- slavik81 8y agoI'm a graphics programmer myself. To be honest, my strategy for OpenGL-related resources is to allocate everything I'll ever need at program start and leak everything at program shutdown. It's simple and efficient and all copies are indeed shallow. However, if I was writing more generic code, I would probably make extensive use of movable but non-copyable containers for my OpenGL resources. You're right that the RAII model sometimes feels a bit limiting for the complexity sometimes found in graphics, but I think part of that was self-inflected by our API design. That seems to be changing. The best-looking technique I've seen for handling Vulkan/DX12 is to make your program more like a compiler. You take a scene as input and you compile it into a command buffer to give the GPU. Your resource handling for stuff like texture slots thus looks more like register allocation. State shadowing is a trivial optimization pass when your GPU code is data. The problem is that when you write RAII classes for GPU resources in the traditional way, C++ sees the GPU state through a tiny pinhole and thus can't optimize very well. When you treat your GPU commands as a program that your C++ program is building, you have more global information about GPU state available, which allows you to make more efficient choices.
- edflsafoiewq 8y agoThat std::unique_ptr has a deleted copy constructor is not minutia! The huge program of C++11 to deprecate auto_ptr, redefine value categories, introduce rvalue-references and move constructors, &c. had the creation of a move-only smart pointer as one of its most proximate goals.
- cjensen 8y agoA thing can be a design goal and minutiae at the same time. The design goal was to reduce accidental errors in code, particularly by the incautious and by learners. But for a practitioner who clearly understands the concept, the exact way in which you must accomplish an operation permitted by the concept is just "however the library wants you to do it" minutiae.
- geezerjay 8y ago> The design goal was to reduce accidental errors in code, particularly by the incautious and by learners No, it really isn't. The whole point of a unique pointer is to ensure that the pointer is in fact unique. Thus, std::unique_ptr is specifically designed to disallow any form of copying.
- Iv 8y agoAny sane interviewer in the field would accept "just don't do that" or "I think the answer is <X> but I would write a test program to make sure and/or check the spec about it"
- otabdeveloper2 8y ago> the minutia that std::unique_ptr<> has no copy constructor. This is not minutae. This is a test if you understand the theory behind ownership semantics.
- xtrapolate 8y agoYou can "test the theory behind ownership semantics" without relying on the intricacies of a C++11 construct (however trivial).
- gpderetta 8y agoUnique_ptr is such a fundamental type that, if one claims to be a c++ programmer, one has to know it and understand how it works.
- xtrapolate 8y ago> "Unique_ptr is such a fundamental type that, if one claims to be a c++ programmer, one has to know it and understand how it works." No. Those utilities weren't standardized before C++11. People wrote their own implementations before that. People had to understand stack unwinding and scoping, memory, RAII, design patterns that relate to allocation/de-allocation of memory, ownership transfer. Then came in the people that decided it'd be a great idea to start quizzing others about C++11 concretions.
- josefx 8y ago> Then came in the people that decided it'd be a great idea to start quizzing others about C++11 concretions. So it has been almost a decade. How much longer before the whole move semantics addition to the language specification becomes relevant to you?
- cjensen 8y agoMove semantics are nice, but they aren't critical or even fundamental to understanding C++. I would bet most C++ programmers do not fully understand them. As a veteran of three decades of C++, I've seen a lot of new hotness turn into old and busted and removed. There's plenty of dark corners where you don't need to look to get a job done.
- gpderetta 8y agoKnowing that unique_ptr has no copy constructor is not a minutuia. It is the whole reason for the type to exist in the first page.