1

I came up with the following table:

+-------------------------------------------------+-----------------------+-----------------+
| Should the callee be able to modify the object? | Is it a large object? |    Semantics    |
+-------------------------------------------------+-----------------------+-----------------+
|                      yes                        |         yes           |    reference    |
|                      yes                        |         no            |    reference    |
|                      no                         |         yes           | const reference |
|                      no                         |         no            |      value      |
+-------------------------------------------------+-----------------------+-----------------+

Now I am not really sure what a large object is. Certainly everything bigger than a pointer, so 8 Bytes. But take a struct with one double and you're already at 8 Bytes.

This answer talks about an overhead of making a reference. Since the question was asked more than 11 years ago, I didn't bother asking there for clarification. Maybe someone could go into detail if this is really a concern since creating a reference it certainly faster than creating a copy, no?

I am not asking when to use which semantics. I also know about move. Much more I am interested in:

  1. Does my table make sense?,

  2. Is size of the object really something to consider when deciding on what semantics to chose, since I think you should almost always use ref (AAR (made up and derived from AAA)) except for built-in's maybe? And

  3. What is a large object? Anything larger than 8 Bytes?

Community
  • 1
  • 1
SebastianWilke
  • 470
  • 1
  • 4
  • 15
  • In addition to size, ownership of member objects is a concern. If object A has member object B, and B should only have a unique owner, then copying A won't work (at best) and will cause hard to identify behavior (at worst). – JohnFilleau Feb 21 '20 at 23:52
  • 3
    It's a bit more complicated than you describe. It is whether copying an object is "expensive", and that doesn't always increase with size of the object. For example, if copying an object involves doing database transactions, that will consume non-trivial time and (during the transaction) system resources regardless of the actual object size. Even without that, the expense of copying data around doesn't simply increase with size - with real hardware circuitry there is often a sweet spot, and variables notably SMALLER or LARGER than a reference will be more expensive to copy than that reference. – Peter Feb 21 '20 at 23:59
  • [And sometimes the compiler cheats](https://en.wikipedia.org/wiki/As-if_rule) and pulls some really nifty sleight of hand. – user4581301 Feb 22 '20 at 00:08
  • please one question per question – 463035818_is_not_an_ai Feb 22 '20 at 00:40
  • 1
    the core guidelines has a similar table https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-conventional – 463035818_is_not_an_ai Feb 22 '20 at 00:48

2 Answers2

3

The answer depends on the type used, not on the size of type.

Look at this struct

struct SmallButHeavyCopy {
    SmallButHeavyCopy(const SmallButHeavyCopy &) {
        std::this_thread::sleep_for(1000s);
    }
};

It's size is smaller than pointer size, but the cost of copy is high.

The question for each type should be:

Create a reference or create copy of the object? What is cheaper?

Tarek Dakhran
  • 2,021
  • 11
  • 21
1
  1. Does my table make sense?,

Sure.

  1. Is size of the object really something to consider when deciding on what semantics to chose,

It can be something to consider, yes. It is not the only thing to consider. It only becomes relevant once you've determined that either value or const ref argument more appropriate than other choices, and you want to choose between them. Even then, there are other considerations besides the size. For example, you'd want to avoid copying any non-trivial types.

  1. What is a large object?

It depends on many things.

Anything larger than 8 Bytes?

Not necessarily.

Here is a rule of thumb: A pointer sized object and anything smaller than that is definitely small. At some point above that, you'll get a large enough object that it becomes cheaper to avoid the copy. That point will depend on how that object is being used.

To find out which one is faster for a particular function in your particular program, you can measure.

eerorika
  • 232,697
  • 12
  • 197
  • 326