C ++ and Swift: how are C ++ stack frames structured? Are the complications of struct inheritance why Swift doesn't support struct inheritance?

A recent developer briefly discussed the topic of struct

inheritance in Swift (or more precisely, the lack of inheritance struct

in Swift). I assumed that the reason Swift doesn't support inheritance struct

is this:

  • struct

    - value types
  • value types are copied between stack frames Inheritance
  • means that the size of a struct

    can change (for example, if Lorry

    inherits from Vehicle

    and Lorry

    adds .weightCapacity

    , then Lorry

    it will take more space than Vehicle

    )
  • Having value type parameters with a size that is not known at compile time will complicate the construction of the stack frame for the caller and data access for the callee

My guess is that it is because of these complications, which would presumably add extra operations to every function call that includes struct

and thus degrades performance, that Swift does not allow inheritance struct

. Is this reasoning correct?

But then I'm at least talking about C ++. C ++ allows inheritance struct

, while C ++ does it with a high degree of performance. This makes me think that my reasoning about Swift not allowing inheritance struct

is wrong. How did C ++ achieve inheritance struct

without negatively impacting performance?

+3


source to share


2 answers


How does C ++ inherit structure inheritance without negatively impacting performance?

In C ++, the compiler always knows the size struct

. But when the base class is copied by value, the object is "sliced": only the members of the base class are copied, and the new object is in no way associated with the original class.



So, if a function wants to do something with Vehicle

without stripping away its unnecessary identification, it must use a pointer or reference to Vehicle

as the function parameter type or return type. But at this point, you no longer have "copied value types between stack frames".

+4


source


Since structs are value types, you must copy them to and from the function. Thus, you could call a non-mutating method with a derived struct, but you could not return the resulting value from it, so

struct Vehicle {
   var color: Color

   mutating func paintWhite() {
       self.color = .White
   } 
}


struct Lorry: Vehicle ...

var lorry = Lorry(color:.Blue)
lorry.paintWhite() // <- wouldn't work, as paintWhite takes inout Vehicle

      



Without the ability to invoke mutation methods, structures would be much less useful and much more confusing.

0


source







All Articles