This repository has been archived by the owner on Oct 15, 2024. 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
-
@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 inline
functions can be part of the public API. I will try to explain my reasoning in the following.The problem with
static inline
Normally, if function is part of Elektra's public API this means there is some code written in a
.c
that 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 inline
function 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 inline
function 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
.so
file andstatic inline
functions exist in client code. If we now change a functions code, this changed version will automatically be used for normal functions. But if astatic inline
function 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 inline
function 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 inline
functionsThe question now is: Can we write
static inline
function in such a way that non-breaking changes never become breaking changes?To which I say: Yes, we can, and
keyDup
is 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
keyDup
is: "Create a (partial) duplicate of aKey
". In other words: "Do a (partial) copy from aKey
into a completely new (empty)Key
". So we need to callkeyNew()
to create the new key and we need to callkeyCopy
to 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 inline
is 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 inline
functions in the public APIstatic inline
function are also breaking changes for thestatic inline function
. (Must be listed in the release notes).[*] Technically,
keyDup()
is of course not part oflibelektra-core
and the way our headers are currently set up, doesn't make it clear where symbols fromkdb.h
belong. But based on the sharedkey*
prefix, I think my reasoning is valid.Beta Was this translation helpful? Give feedback.
All reactions