5 ms·
> C++ And using pointers instead of references.
by Koshkin 4y ago
> C++
And using pointers instead of references.
- wudangmonk 4y agoyes? what am I missing here?. I've always prefered pointers in my c++ code.
- dxuh 4y agoIt shouldn't be a matter of preference. Use a pointer if you need it to be relocatable or if you need it to be optional (it may be nullptr). Otherwise use a reference.
- pizza 4y agoI am not familiar with the capabilities of the compiler but is there any optimization reason to prefer references as well? Like the compiler may be able to figure out an efficient way to keep a referenced object ‘nearby’ for subsequent function calls that also refer to the object, maybe in some register or reordering which code gets run when. Whereas sometimes the compiler might not be able to do something like that with a pointer, incurring mem access costs. Hm slightly tangential but could you install some kind of page-fault handler on a reference such that the control flow jumps on write back to the last place it was accessed? Not that you’d want to do that in the real world, but it would be an interesting “pub-sub” type control flow..
- Sharlin 4y agoIn C++, there are no differences between pointer and reference semantics except that the former are a) nullable and b) reseatable (can be changed to point to something else).
- amalcon 4y agoThe other major use-case is where other code constrains you, e.g. it's being passed as a callback to a C library. There are also a number of cases where passing a pointer into a template function can be more concise. E.g. since pointers are iterators, if you have a generic function that iterates over things and you just want it to look at one thing (or zero) for testing, you can usually do this with pointer arithmetic.
- cpgxiii 4y agoCode following this style (e.g. lots of code following GSG or GSG-derived styles), tends to have large amounts of void func(ParamType* param) { assert(param != nullptr); ... } because passing via pointer introduced undesired nullability. And if that null pointer check isn't present, or is done wrong, you've easily introduced the potential for undefined behavior into the codebase. C++ specifically gives you mutable references to express the desired behavior in these cases, and using a nullable (and memory-unsafe nullable at that) pointer is actively less clear (you now need to document the non-null precondition separately, rather than in the signature itself).
- Kamq 4y ago> introduced the potential for undefined behavior Small quibble, C++ has the capability to be low level enough that the potential for UB is always there. Even with a reference, you could be dealing with a completely random chunk of memory that someone told the compiler to interpret as the data type in question. The quibble is the presentation of this as introducing the possibility of UB (the word introduced implies it wasn't already there), instead of used as a technique for minimizing the already present potential of UB.
- Ferrotin 4y agoYou are just wrong here. References were not added to C++ for that reason. Pointers can be presumed in some code bases not to be null with nullability being the unusual and documented scenario.
- kllrnohj 4y ago> Pointers can be presumed in some code bases not to be null with nullability being the unusual and documented scenario. So document it regardless instead https://releases.llvm.org/3.8.0/tools/clang/docs/AttributeReference.html#nonnull https://releases.llvm.org/3.8.0/tools/clang/docs/AttributeRe...
- cpgxiii 4y agoI didn't claim that's why they were added, I said that's what they allow you to express. > Pointers can be presumed in some code bases not to be null with nullability being the unusual and documented scenario. Just because you can train your users to assume/document when nullability is allowed, doesn't make it a better option than using a language construct that would make it explicit.
- mshockwave 4y agonobody says you should always use reference instead of pointer in C++
- bodhiandphysics 4y agoLots of people say this... they’re wrong but the day this
- leni536 4y agoI do prefer references, because they can't be null. It is less state to worry about. I agree that not having explicit out-parameters makes this a trade-off. It is possible to use an out-parameter wrapper type to get the best of both worlds, but nobody does this.
- deleted 4y ago[deleted]
- dragontamer 4y agoWhich of the following code potentially modifies foobar? int foobar; f(foobar); g(&foobar); Well, in C, "g" is the only function that might modify foobar. In C++ however, the reference type f(int& x); can make f also modify foobar. For some coders, it is preferable to have this explicit & reminder on their code, to see cases like "g" rather than possible-modifications that occur with "f"-style code. Personally speaking, I kinda switch between the two styles depending on mood / the situation. I'd think that the dereferences on "atomics" however need to be incredibly explicit however, so "atomic" code will almost certainly be "g" style, rather than "f".
- cpgxiii 4y agoThe problem with this is that once you get any deeper than the first call, that helpful "&arg" goes away and it's just "arg". I would argue this sometimes-there single character is incredibly brittle for the claimed benefits, and illustrative of the unwillingness of large parts of the C++ community to use any reasonable tools that would do a better job instead (e.g. very basic syntax highlighting would be far more consistent in indicating mutability).
- kevin_thibedeau 4y ago> that helpful "&arg" goes away and it's just "arg". You still get a reminder it's a pointer by the * and -> notation.
- cpgxiii 4y agoThat only goes so far - without reasonable method names you still don't know if the operation actually mutates the parameter, e.g. in void func(ParamType* param) { ... auto res_1 = param->Operation1(1); auto res_2 = param->Operation2(2); ... } the presence of -> doesn't tell you which method mutates. The only thing that would tell you that would be knowing which method is const.
- dragontamer 4y ago> The problem with this is that once you get any deeper than the first call, that helpful "&arg" goes away and it's just "arg". There's a HUGE difference from a "int& foo" and a "int* foo". ESPECIALLY if I'm doing incredibly sophisticated atomic operations, memory-barrier, and atomic operations (IE: atomic<int>& vs atomic<int>*). Take a guess which one I'm more comfortable passing around. This isn't a case of "param->Operation1(1)" like you're talking about. This is a simple integer being used in some of the most complex, sophisticated, low-level optimizations known to the modern programmer. Knowing when, where, why, and how these things are dereferenced is the entire damn point of memory-barriers and atomics. I want _NO_ surprises, at all. At least, within the context of "C++ Concurrency Models". To be honest, this is the stuff that causes me to run away screaming. But if I'm forced to write code involving the words "compare-and-swap", "atomic", or "barrier", you damn well bet that I'm going to be doing it with "int*" rather than "int&". -------- Every style of code has its place. When dealing with atomics, I definitely prefer pointers over references. If you're running around in object-oriented land, you probably don't care and have modest benefits to the reference. But the minute you start studying "A-B-A" problems and the difference between "load-acquire" vs "load-consume" and the possible memory-orderings that can happen, you suddenly want to become extremely explicit over your dereferencing. -------- "When" did the dereference occur? Is it compatible between Thread#1 and Thread#2? Are there any weird "gotchas" that could occur? Has the dependencies you need been ordered correctly in all threads that are active? If you're unaware of what's going on here, give this a readover. https://en.cppreference.com/w/cpp/atomic/memory_order https://en.cppreference.com/w/cpp/atomic/memory_order I promise you, you'll have some headaches. This is by far the hardest subject in all of low-level programming I've come across. And being more explicit about when the dereferences happen is very useful.
- spacechild1 4y agoCompletely off-topic...