12

This may be a very basic question but somehow it got me tricked... when I write test code, it seems to work, but something is going wrong in production.

// Header file
#define length 100
typedef struct testStr_t {
    int a;
    char b;
    char t1[length];
    char t2[length];
} test;

void populateTest(test*);

// source file
test test1;
test test2;
populateTest(&test1);
test2 = test1;

Will test2 be a deep copy of test1? Or are there gotchas here? Does it matter if the code is compiled with a C compiler or a C++ compiler?

Thanatos
  • 42,585
  • 14
  • 91
  • 146
Kiran
  • 5,478
  • 13
  • 56
  • 84
  • 7
    there isn't really any notion of deep vs. shallow copying in C++. Everything is a value, and values are just copied. – jalf May 23 '11 at 21:31
  • @Cubbi: Why did you delete your answer? It was good! – Lightness Races in Orbit May 23 '11 at 21:33
  • 4
    @jalf: Huh? There is _absolutely_ a notion of deep vs shallow copying. OK, not to the language, and not if you're sensible and use RAII; but although the _need to make a distinction_ can be avoided, that in no way means that there is none. – Lightness Races in Orbit May 23 '11 at 21:33
  • @jalf - There isn't any concept of iterators in the C++ language, but we impose the concept to make things easier to understand and code. – Chris Lutz May 23 '11 at 21:34
  • 4
    I'm with jalf here. And the idea of a deep versus shallow or (maybe medium?) has always struck me as ridiculous. The different concepts might work for smalltalk (but I would argue that one of the reasons why ST has never caught on is that you have to think about such things), but it doesn't work for C++ - a copy is a copy. –  May 23 '11 at 21:38
  • Thanks. This helpful discussion confirms my assumptions. Need to debug what else is going wrong.. – Kiran May 23 '11 at 21:52
  • 3
    @Chris So should we impose the concept of, say, UFOs? Some things (like iterators) fit well into the C++ way of doing things and some things (like deep/shallow copy) don't. –  May 23 '11 at 22:00
  • 1
    What I find interesting is discussing *deep* versus *shallow* copy in a one level structure. Either it is copied or not. If it were holding other objects through pointers you could argue about *shallow* (just the pointer) or *deep* (make a copy of the pointed to objects too) copies... – David Rodríguez - dribeas May 23 '11 at 22:51
  • 1
    @Neil - The concept of deep copies _does_ fit well into the C++ way of doing things. That's why we overload `operator=` to copy pointer data members instead of just using the default version (which copies pointers). We don't usually want shallow copies of objects, but it's important to understand the concepts to understand why we want certain things, and when we want to use them. – Chris Lutz May 23 '11 at 23:40
  • 2
    Shallow copy vs deep copy is the wrong dichotomy in C++. There is only "correctly copies", "broken copy code", and "noncopyable". Adding a data member can break certain methods (such as copy ctor and op=), but *adding data members can always break these methods* (including default ctor, destructor, etc.). – Fred Nurk May 24 '11 at 02:00
  • @Chris: `operator=` doesn't do a deep copy it does a *correct copy*, as @Fred says. it is pretty common for classes to hold a pointer to something they don't own, and which should not be copied, among all the other members which *are* fully copied. Thus, their copy is not entirely deep. It's merely *correct*. – jalf May 24 '11 at 06:10
  • 1
    @Chris: but deep vs shallow copy isn't a useful distinction to make, any more than "C++ code with an even number of characters in the source code" vs "C++ code with an odd number of characters". Sure, you can look at any given piece of source code and say if it fits into one or the other category, but it's not *useful* (and in the case of deep vs shallow, a lot of code won't be either. It'll be a mixture) – jalf May 24 '11 at 06:17
  • 1
    The point is that when you wish to copy an object in, say, Java or Smalltalk, you have to decide *how* you want to copy it. So considering the two extremes makes sense, because the language forces you to do so. In C++, every object defines its own *correct* copy operation. It doesn't matter if it is technically shallow or deep, or some hybrid, because it's simply *the* copy operation – jalf May 24 '11 at 06:18

2 Answers2

11

Deep copies are only hindered by pointers, so your struct will be copied correctly in C. It'll work in C++ as well unless you define your own operator= that doesn't copy correctly. You only need to define operator= for types with pointers, since a shallow copy of a pointer will copy the pointer but share the data.

Chris Lutz
  • 73,191
  • 16
  • 130
  • 183
3

My answer relates to C++. I can only guess that it's still appropriate for C.

It will be a shallow copy.

If the objects contained pointers t1 and t2, each containing the location of some indirect, dynamically-allocated memory block, you'd need a deep copy.

However, the objects contain direct objects of an actual array time, so you're fine with the shallow copy.

(It's slightly misleading that this works, yet you can't manually assign to array objects yourself!)

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055