Unless you ditch optimizations completely, it is hard to know without looking at the generated asm. Of course you can make educated guesses.
struct S {
int m_field;
int field() { return m_field; }
void field(int c) { m_field = x; }
}
just to future proof the field access. Don't bother with the access functions until they are actually needed.If anything, I would argue that explicit accessors make it clearer because in e.g. C# you can't write a method that looks like a getter (but mutates state) by accidentally naming it as such. If someone made something a property, that's because they thought its semantics are property-like, which includes not mutating global state. Sure, people will still get that wrong occasionally, just as they run mutating "get" methods, but it is surprisingly rare.
When I was new to their corresponding GUI frameworks, the dot + property notation was appealing because it looked clean. However, as I got more experienced I'm no longer seeing the advantage of saving two parentheses characters at the expense of potentially hiding function calls where anything can happen.
I'm not sure why D joined the club given it doesn't have a corresponding de facto GUI framework, and its users even discourage it.
underneath there is literally assembly to take current state, push it to the stack, then jump into another location in memory and start executing.
And then when done, do the reverse. jump back to another memory location and pop everything back off the aforementioned stack and into registers.
So I overrode the field access that operated directly on the byte array.
PS: It was in Kotlin, using @get/@set, but it doesn't matter for the philosophy.
Attribute access is reading a value, invoking a function is different (as mentioned, using a stack, etc.), although it is certainly possible a function only reads and returns a value.
All that to say my answer is yes, providing flow control mechanisms makes it flow control... and falling trees make a sound!