This repository was archived by the owner on Feb 16, 2025. It is now read-only.
Replies: 1 comment 3 replies
-
|
Do I understand this correctly: The assumption here is that the client code uses only the In that case we are discussing a scenario that seems very rare to me. Am I overlooking something? |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
@markus2330 recently voiced concern about the use of
static inline("alias") functions in the public API (e.g in #3730 (comment), #3736 (comment) and #3606). We should discuss how we want to handle these functions moving forward.IMO, if use carefully,
static inlinefunctions can be part of the public API. I will try to explain my reasoning in the following.The problem with
static inlineNormally, if function is part of Elektra's public API this means there is some code written in a
.cthat is compiled into a library (e.g.libelektra-core). This library exports a symbol that can be used to execute the code. The symbols are declared in header files (e.g.kdb.h) for clients to include into their code.With a
static inlinefunction this is different. The whole function is written in a header file (e.g.kdb.h). The client code does not link to our library and execute the code contain in it. Instead every time the header is included, the compiler copies the wholestatic inlinefunction into the target file. Depending on various factors, the compiler might then inline the function into it's call sites. Whether this happens is not really important for the public API considerations.The important difference is that normal functions exist in our
.sofile andstatic inlinefunctions exist in client code. If we now change a functions code, this changed version will automatically be used for normal functions. But if astatic inlinefunction is changed, the client code has to be recompiled. We call a change where client code has to be recompiled is a "breaking change".So the problem with
static inlinefunction is that a change that might not be breaking otherwise can become a "breaking change" by making a functionstatic inline.Avoiding breaking changes in
static inlinefunctionsThe question now is: Can we write
static inlinefunction in such a way that non-breaking changes never become breaking changes?To which I say: Yes, we can, and
keyDupis such an example.libelektra/src/include/kdb.h.in
Lines 210 to 213 in 5702ce0
To be clear, we are interested in changes to the function body that normally don't require changes to the call site.
So what could we theoretically change in
keyDup:keyNew()keyCopy()keyNew()keyCopy()1 and 2 will never change. The definition of
keyDupis: "Create a (partial) duplicate of aKey". In other words: "Do a (partial) copy from aKeyinto a completely new (empty)Key". So we need to callkeyNew()to create the new key and we need to callkeyCopyto make the copy. The definition also forces us to use these exact arguments tokeyNew(), because otherwise we wouldn't get a completely new (empty)Key.4 is also a non-issue. We already now, that the first parameter for
keyCopy()must be a new key, so that can't change. The other parameters to directly passed through from the call-site, so we can't change them either without requiring call-site changes.There is one important fact we have ignored up until now: What if
keyCopy()orkeyNew()change in such a way that we must pass different arguments to get the same result (e.g. the first and second arguments ofkeyCopy()are swapped)? This might indeed require a change insidekeyDup()without needing a call-site change. But this is actually also a non-issue. Any such change would by definition be breaking change tokeyCopy()orkeyNew(), because the change requires a change to the call-site (in this casekeyDup()).So why is a breaking change to
keyCopy()orkeyNew()not a problem? IMOkeyCopy(),keyNew()andkeyDup()are all part of the same module (libelektra-core[*]). That means anyone using this module has to check their code and might need to recompile anyway.In the end the only difference that results from
keyDup()beingstatic inlineis this: A client that useskeyDup(), but does not usekeyCopy()will need to recompile, if there are breaking changes inkeyCopy()that can be "hidden" inkeyDup()'s implementation (e.g. first to arguments ofkeyCopy()are swapped). IMO this is not a problem, as long as we write our release notes correctly, so people know when to recompile. Specifically, this means that all breaking changes tokeyCopy()orkeyNew()must be considered breaking changes tokeyDup()as well and this must be stated in the release notes.Proposal: Rules for
static inlinefunctions in the public APIstatic inlinefunction are also breaking changes for thestatic inline function. (Must be listed in the release notes).[*] Technically,
keyDup()is of course not part oflibelektra-coreand the way our headers are currently set up, doesn't make it clear where symbols fromkdb.hbelong. But based on the sharedkey*prefix, I think my reasoning is valid.Beta Was this translation helpful? Give feedback.
All reactions