Background: This is an old topic I studied multiple times, but still unfamiliar. I think most people don’t work at such a low level?
Q1: Can return a malloc object by reference? I doubt it. I think the address is lost and there’s no way to free it.
Q1b: if you only have a reference to a heap object, how can you delete it? See https://bintanvictor.wordpress.com/?p=10505&preview=true
Q: Can return a static local by reference? I think so but not popular
Q: Can return a by-ref argument by reference? No need (but legal) since the caller already has that reference. You could return it in an if/else
Q: can return another object in scope by reference? Yes
Return-by-non-const-ref is often used in operator overloading to support counter.increment()
The assignment operator returns a const ref.
Every variable that holds data is an object. Objects are created either with static duration (by defining rather than declaring the variable), with automatic duration (declaration alone) or with dynamic duration via new/malloc().
That’s the short version. Here’s the long version:
– stack variables (including function parameters) – each stack object has a name (multiple possible?) i.e. the host variable, like a door plate on the memory location. When you clone a stack variable you get a cloned object. (Advanced — You could create a reference to the stack object, when you pass the host variable by-reference into a function. You should never return a stack variable by reference)
– heap objects – have no name no “host variable” no door plate. They only have addresses. The address could be saved in a “pointer object”, which is a can of worm. (In many cases, the address is passed around without any pointer object)
– non-local static objects — are more tricky. The variable(i.e. name) is there after you declare it, but it is a door plate without a door. It only becomes a door plate on a storage location when you allocate storage i.e. create the object by “defining” the host variable. There’s a one-definition-rule for static objects, so most of the time you first declare the variable without defining it, then you define it elsewhere. See https://bintanvictor.wordpress.com/2017/05/30/declared-but-undefined-variable-in-c/
If you intend to store arbitrary binary data, you should use …. unsigned char ! C has no “byte” data type.
It is the only data type that is guaranteed (by the ANSI C Standard) to have no padding bits. So all 8 bits in an unsigned char contribute to the value. None of them is a padding character.
I find this stackoverflow comment (http://stackoverflow.com/questions/21092415/force-c-structure-to-pack-tightly) rather concise :
The problem is that the creator of the file took no time to properly byte align the data structures and everything is packed tight.
· Your kernel should export C functions with a conventional calling convention for the registration of plugins and functions. If you use a C++ function then you are forcing all plugin authors to use the same compiler version, since many things like C++ function name mangling, STL implementation and calling conventions are compiler specific.
· Plugins should only export C functions like the kernel.
This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of Intercontinental Exchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.
See also post on rval reference
int* p1 = &foo(); // ok, foo() is an lvalue
foo(5) = 42; // (A) ok, foo() is an lvalue. Java doesn’t allow it but does allow …
java ## foo=42; // (B)
p1 = … //ok
*p1 = … //ok
*(…) = …//ok. Most deference expressions can be L-value expressions
C++ lets you overload the subscript operator i.e. brackets so (B) can be implemented as a shorthand for (A).
C# indexer and property both look like fields of an object (fields are L-values), but both get converted to getter/setter functions. Therefore they don’t refer to memory locations. Therefore an indexer/property can’t be ref or out arguments. They can be used as regular method arguments though, because they are good enough as R-values.