3

I want something conceptually like this in c/c++

struct first{
   int a,b,c;
}my1;

struct second{
   int a,b,c;
   int extended;
}my2;

and somehow be able to have

my2=my1; 

(meaning only copy the same parts. leaving extended untouched)

I thought of solving it as

struct second{
     first first_;
     int extended;
 }my2;

and have

my2.first_ = my1;

but it is a bit ugly for me. is there any more clear solution for this? probably it is something like extending a structure or something?

Soren
  • 14,402
  • 4
  • 41
  • 67
Roozbeh G
  • 427
  • 4
  • 18
  • C or C++, or the common subset of both? – CB Bailey Apr 18 '14 at 22:53
  • You somehow have to specify the the thing you want assigned-to, and the part of that thing you want modified. So your solution is about as concise as it can get. (The "_" is ugly indeed, but you can pick a different name to fix that). – Ira Baxter Apr 18 '14 at 22:53
  • 2
    If you want to do it in C++ then grab your C++ book and read about Copy Constructor and Assignment Operator. – Soren Apr 18 '14 at 22:55
  • I am more intrested in C as I want to later copy memoris assigned to these for cuda program. I am frightened that c++ might introduced additional memory overhead which might not get trapped in moving data.(just thinking) I also saw this http://stackoverflow.com/questions/2807138/can-i-access-a-struct-inside-of-a-struct-without-using-the-dot-operator?rq=1 which gives similar answer to use struct second: public first{ int extended}; but still for assignment I cant do my2=my1 – Roozbeh G Apr 18 '14 at 22:55
  • 2
    Update the question to be only about C then – clcto Apr 18 '14 at 22:57
  • You can use `memcpy` `memcpy(&second, &first, sizeof(first));` –  Apr 18 '14 at 22:58

3 Answers3

2

Like that:

struct second : first
{
    int extended;

    second& operator=(const first& f)
    {
        first::operator=(f); extended = 0; return *this;
    }
};
iavr
  • 7,547
  • 1
  • 18
  • 53
  • this looks great. can you explain code inside { }. what does first::operator=(f) does? – Roozbeh G Apr 18 '14 at 23:01
  • @Soren Right, thanks. Which brings the issue of what is `extended`'s default value, which is a constructor's job... anyway, let's say it's `0`. – iavr Apr 18 '14 at 23:06
  • @RoozbehG `first::operator=(f)` does whatever this (`second`) object seen as `first` would do when assigned another `first` `f`; that is, implicitly assign its `a,b,c` members the corresponding values from `f`. – iavr Apr 18 '14 at 23:18
  • 1
    no need to override `operator=`: just use `*(first*)&object = value;`, which works for both C and C++. – Deduplicator Apr 18 '14 at 23:26
  • @Deduplicator The question had a `c++` tag (also in title) that was later removed. I wouldn't even be looking at questions about C. – iavr Apr 18 '14 at 23:31
  • @iavr: Yes, it also had a C++ tag, which is why I didn't say anything against your answer using C++. Still, it should have been useable for both imho, as both tags were there, now that you remind me. – Deduplicator Apr 18 '14 at 23:34
  • @Deduplicator I will delete my answer in a few minutes then. – iavr Apr 18 '14 at 23:37
  • @iavr: Just add a bit for C then, and incorporate these comments. – Deduplicator Apr 18 '14 at 23:48
1

Somewhat equally ugly, but here it is :

my1 = *(first*)&my2;
Flibustier
  • 90
  • 7
  • I think I can use this too. but could it be somehow possible that compiler generate some paddings differently between my1 and my2 variables so their memory sizes dont match and this fails? – Roozbeh G Apr 18 '14 at 23:02
  • 1
    @Roozbeh G, it could. However, there is another rule that if two structs with a common initial sequence are both members of a union, then it is OK to alias the common iniital sequence. So if you include the code `union X { struct first f; struct second g; };` then it guarantees that Flibustier's suggestion works even though you never instantiate that union. AFAIK there are no implementations that would use a different structure if the union were not present, so people tend to just omit it and assume the compiler is not perverse. – M.M Apr 19 '14 at 01:28
  • @Matt What about the other way round `my2 = *(second*)&my1;` ? My assumption is you can't since sizeof(my2) > sizeof(my1). – Flibustier Apr 19 '14 at 08:20
  • Yeah that would access memory you don't own. – M.M Apr 20 '14 at 04:58
0

You can overload the = operator for struct second:

second & operator=(const first & s) {
    this->a = s.a;
    this->b = s.b;
    this->c = s.c;
    return *this;
}
yizzlez
  • 8,757
  • 4
  • 29
  • 44