Inline function cannot access non-public-API: #PublishedApi vs #Suppress vs #JvmSynthetic - inline

In Kotlin, when I have a non-public member and an inline fun that calls it, there's a compilation error saying:
Error:(22, 25) Kotlin: Public-API inline function cannot access non-public-API private fun f(): Unit defined in com.example
I found several ways to call my function inside a public inline fun, but which is the best way to do it?
Suppose I have a private fun f() { }. Then the options I found are:
fun f() { }
Just make it public. This is the baseline solution, but if the others turn out to have major disadvantages, this can end up the best one.
#PublishedApi internal fun f() { }
Introduced in Kotlin 1.1-M04, the annotation can be applied to an internal member, making it effectively public. The implication I noticed is that any library user will still be able to call it from Java code, that's what I don't like about it.
#Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") inline fun g() { f() }
Found in the stdlib sources, this annotation seems to suppress the error when applied to the calling function. But what are its limitations? Can it only be used for inline functions? Will the resulting program fail under some circumstances? I tried to call a non-inline function from an inline one with this trick, and it worked, but it looks suspicious.
#JvmSynthetic #PublishedApi internal fun f() { }
Combine the second solution with the synthetic flag in the bytecode. I'm not sure if this is a correct usage of #JvmSynthetic, but this appears to hide the function from Java code, which solves the problem of the #PublishedApi internal.
So, which of these solutions is the best way call a non-public function from a public inline one? What are the downsides of each solution that I don't see?

#PublishedApi internal is the intended way of exposing non-public API for use in public inline functions.
That #PublishedApi internal member becomes effectively public and its name doesn't get mangled (if you noticed the opposite, please file a bug).
#Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") is a band-aid workaround in the lack of #PublishedApi based on suppressing an error and therefore isn't recommended. With the introduction of #PublishedApi this suppression is going to be cleaned from the standard library.
#JvmSynthetic combined with #PublishedApi is an interesting approach, however it can cause some problems while debugging, though I'm not sure.

Related

override/redefine a C-Function which has a section attribute

I have the case where I need to overwrite some C-Functions of an SDK we use. The SDK is compiled as a lib and the functions we need to override are marked with
__attribute__((weak))
This works as it should when linking.
We override those functions then later in our files with the wanted definition.
Background:
The reason is that the SDK is not working in a standalone way but always needs a special tool which generates some global objects which are needed in the init-functions of the SDK. And we wanted to get rid of the tool and thus need new init-functions which do not rely on the global objects but on passing the configuration via pointer. Those functions are added additionally and no SDK-functions are removed.
Also the SDK shall not be altered in a way you can't use it anymore with the tool. So it must support both features, with the smallest changes possible which will not break the API and add support for the new API by us without the tool.
So following up, if we now have a function which has already an attribute defined, which references to a section like
void __attribute__((section(".text.random"))) Random_init(){}
it is not possible to override Random_init.
I do not get errors like it was redefined or anything but undefined symbols while linking which refer to those global objects, which of course are not generated anymore and are only used by the function which shall be overriden. And this works for all other 20 init-functions only for this one it does not and the only difference is the attribute already there.
I tried adding it together:
void __attribute__((weak, section(".text.random"))) Random_init()
which also does not work.
I also tried to add the attribute to the redefinition, but this also does not help.
We cannot just erase the section-attribute since it needs to be there for all the entities using the tool.
The compiler we use is a clang based TI LTS1.3.1-compiler.
I would like to provide a minimal example but since this combination only works with the sdk-code beeing compiled to a lib first, I just cannot.
I just try to show it:
SDK-function which is compiled inside the lib, c-file "Random.c":
extern RandConfig gRandConfig[];
extern int32_t gRandConfigNum;
void __attribute__((weak, section(".text.random"))) Random_init()
{
uint32_t i;
for (i = 0; i < gRandConfigNum; i++)
{
Random_setSpecial(i,
(void*)gRandConfig[i].baseAddr,
gRandConfig[i].size,
&gRandConfig[i].attrs
);
}
}
related Header-file, Random.h:
void Random_init();
The gRandConfig and gRandSpecialConfig are produced in code by the tool, which are then linked against the library and we don't want to use them anymore.
All the context where this shall happen is in C but the libs are used from C++-context.
So for example this is how the override would look like in our .cpp-files:
#include "Random.h"
extern "C"
{
void Random_init()
{
}
}
The result when linking:
undefined first referenced
symbol in file
--------- ----------------
gRandConfig ../../../../sdk-build/sdk.lib<Random.obj>
gRandConfigNum ../../../../sdk-build/sdk.lib<Random.obj>
The included header by the sdk also has guards for __cplusplus. So it shouldn't be a language issue.
Also we issued the compiler to compile with -ffunction-sections which shall at least help to sort unneeded functions out later on. But anyway it does not. Even when the function gets never called by anyone.
A dirty solution would be to just add dummy-variables for this one, so it's satisfied and does not complain but as you can imagine, that would be a workaround which produces a lot of problems later on and also takes space where we need every Byte of space.
Could it be that an section-function-attribute prevents the function from being overriden? I did not find anything at the gnu-documantation which says that one cannot override a function with an attribute.

Can a function know what's calling it?

Can a function tell what's calling it, through the use of memory addresses maybe? For example, function foo(); gets data on whether it is being called in main(); rather than some other function?
If so, is it possible to change the content of foo(); based on what is calling it?
Example:
int foo()
{
if (being called from main())
printf("Hello\n");
if (being called from some other function)
printf("Goodbye\n");
}
This question might be kind of out there, but is there some sort of C trickery that can make this possible?
For highly optimized C it doesn't really make sense. The harder the compiler tries to optimize the less the final executable resembles the source code (especially for link-time code generation where the old "separate compilation units" problem no longer prevents lots of optimizations). At least in theory (but often in practice for some compilers) functions that existed in the source code may not exist in the final executable (e.g. may have been inlined into their caller); functions that didn't exist in the source code may be generated (e.g. compiler detects common sequences in many functions and "out-lines" them into a new function to avoid code duplication); and functions may be replaced by data (e.g. an "int abcd(uint8_t a, uint8_t b)" replaced by a abcd_table[a][b] lookup table).
For strict C (no extensions or hacks), no. It simply can't support anything like this because it can't expect that (for any compiler including future compilers that don't exist yet) the final output/executable resembles the source code.
An implementation defined extension, or even just a hack involving inline assembly, may be "technically possible" (especially if the compiler doesn't optimize the code well). The most likely approach would be to (ab)use debugging information to determine the caller from "what the function should return to when it returns".
A better way for a compiler to support a hypothetical extension like this may be for the compiler to use some of the optimizations I mentioned - specifically, split the original foo() into 2 separate versions where one version is only ever called from main() and the other version is used for other callers. This has the bonus of letting the compiler optimize out the branches too - it could become like int foo_when_called_from_main() { printf("Hello\n"); }, which could be inlined directly into the caller, so that neither version of foo exists in the final executable. Of course if foo() had other code that's used by all callers then that common code could be lifted out into a new function rather than duplicating it (e.g. so it might become like int foo_when_called_from_main() { printf("Hello\n"); foo_common_code(); }).
There probably isn't any hypothetical compiler that works like that, but there's no real reason you can't do these same optimizations yourself (and have it work on all compilers).
Note: Yes, this was just a crafty way of suggesting that you can/should refactor the code so that it doesn't need to know which function is calling it.
Knowing who called a specific function is essentially what a stack trace is visualizing. There are no general standard way of extracting that though. In theory one could write code that targeted each system type the software would run on, and implement a stack trace function for each of them. In that case you could examine the stack and see what is before the current function.
But with all that said and done, the question you should probably ask is why? Writing a function that functions in a specific way when called from a specific function is not well isolated logic. Instead you could consider passing in a parameter to the function that caused the change in logic. That would also make the result more testable and reliable.
How to actually extract a stack trace has already received many answers here: How can one grab a stack trace in C?
I think if loop in C cannot have a condition as you have mentioned.
If you want to check whether this function is called from main(), you have to do the printf statement in the main() and also at the other function.
I don't really know what you are trying to achieve but according to what I understood, what you can do is each function will pass an additional argument that would uniquely identify that function in form of a character array, integer or enumeration.
for example:
enum function{main, add, sub, div, mul};
and call functions like:
add(3,5,main);//adds 3 and 5. called from main
changes to the code would be typical like if you are adding more functions. but it's an easier way to do it.
No. The C language does not support obtaining the name or other information of who called a function.
As all other answers show, this can only be obtained using external tools, for example that use stack traces and compiler/linker emitted symbol tables.

Exposing functions instead of constants for describing library features

I've noticed that in a lot of library, version informations, as well as informations on the availability of special features that may differ or be absent depending on the build, are made accessible to client applications not by a constant, but by a function call returning a constant, e.g.:
const char *libversion(void) {
return "0.2";
}
bool support_ssl(void) {
return LIB_SSL_ENABLED; /* whatever */
}
instead of simply:
const char *libversion = "0.2";
bool support_ssl = LIB_SSL_ENABLED;
Is there a practical reason for doing this, or is it only some kind of convention?
Is there a practical reason for doing this, or is it only some kind of convention?
I'd say both…
A practical reason I see for this, is that when you distribute your library, your users install a compiled version of it as a shared object, and access its data using the header. If the constant is accessible through a function, its prototype is declared in the header, but the value is defined in the compilation unit, linked in the shared object file. Edit: I'm not saying it's not possible, but a good reason for doing so is to keep the possibility to keep the API stable, while switching from a constant value to a calculated value for a given function, cf reason #3.
Another practical reason I can see is that you could access that API using some sort of "middleware", like corba, that enables you to access functions, but not constants (please be kind with me if I'm wrong about that particular point, I haven't done any CORBA in 10 years…).
And in the end, it's somehow good OOP convention, the header file being a pure functional interface, and all the members being encapsulated enabling a full decoupling of the inner workings of the library and the exposed behaviour.

When is "inline" ineffective? (in C)

Some people love using inline keyword in C, and put big functions in headers. When do you consider this to be ineffective? I consider it sometime even annoying, because it is unusual.
My principle is that inline should be used for small functions accessed very frequently, or in order to have real type checking. Anyhow, my taste guide me, but I am not sure how to explain best the reasons why inline is not so useful for big functions.
In this question people suggest that the compiler can do a better job at guessing the right thing to do. That was also my assumption. When I try to use this argument, people reply it does not work with functions coming from different objects. Well, I don't know (for example, using GCC).
Thanks for your answers!
inline does two things:
gives you an exemption from the "one definition rule" (see below). This always applies.
Gives the compiler a hint to avoid a function call. The compiler is free to ignore this.
#1 Can be very useful (e.g. put definition in header if short) even if #2 is disabled.
In practice compilers often do a better job of working out what to inline themselves (especially if profile guided optimisation is available).
[EDIT: Full References and relevant text]
The two points above both follow from the ISO/ANSI standard (ISO/IEC 9899:1999(E), commonly known as "C99").
In §6.9 "External Definition", paragraph 5:
An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.
While the equalivalent definition in C++ is explictly named the One Definition Rule (ODR) it serves the same purpose. Externals (i.e. not "static", and thus local to a single Translation Unit -- typically a single source file) can only be defined once only unless it is a function and inline.
In §6.7.4, "Function Specifiers", the inline keyword is defined:
Making a function an inline function suggests that calls to the function be as
fast as possible.[118] The extent to which such suggestions are effective is
implementation-defined.
And footnote (non-normative), but provides clarification:
By using, for example, an alternative to the usual function call mechanism, such as ‘‘inline substitution’’. Inline substitution is not textual substitution, nor does it create a new function. Therefore, for example, the expansion of a macro used within the body of the function uses the definition it had at the point the function body appears, and not where the function is called; and identifiers refer to the declarations in scope where the body occurs. Likewise, the function has a single address, regardless of the number of inline definitions that occur in addition to the external definition.
Summary: what most users of C and C++ expect from inline is not what they get. Its apparent primary purpose, to avoid functional call overhead, is completely optional. But to allow separate compilation, a relaxation of single definition is required.
(All emphasis in the quotes from the standard.)
EDIT 2: A few notes:
There are various restrictions on external inline functions. You cannot have a static variable in the function, and you cannot reference static TU scope objects/functions.
Just seen this on VC++'s "whole program optimisation", which is an example of a compiler doing its own inline thing, rather than the author.
The important thing about an inline declaration is that it doesn't necessarily do anything. A compiler is free to decide to, in many cases, to inline a function not declared so, and to link functions which are declared inline.
Another reason why you shouldn't use inline for large functions, is in the case of libraries. Every time you change the inline functions, you might loose ABI compatibility because the application compiled against an older header, has still inlined the old version of the function. If inline functions are used as a typesafe macro, chances are great that the function never needs to be changed in the life cycle of the library. But for big functions this is hard to guarantee.
Of course, this argument only applies if the function is part of your public API.
An example to illustrate the benefits of inline. sinCos.h :
int16 sinLUT[ TWO_PI ];
static inline int16_t cos_LUT( int16_t x ) {
return sin_LUT( x + PI_OVER_TWO )
}
static inline int16_t sin_LUT( int16_t x ) {
return sinLUT[(uint16_t)x];
}
When doing some heavy number crunching and you want to avoid wasting cycles on computing sin/cos you replace sin/cos with a LUT.
When you compile without inline the compiler will not optimize the loop and the output .asm will show something along the lines of :
;*----------------------------------------------------------------------------*
;* SOFTWARE PIPELINE INFORMATION
;* Disqualified loop: Loop contains a call
;*----------------------------------------------------------------------------*
When you compile with inline the compiler has knowledge about what happens in the loop and will optimize because it knows exactly what is happening.
The output .asm will have an optimized "pipelined" loop ( i.e. it will try to fully utilize all the processor's ALUs and try to keep the processor's pipeline full without NOPS).
In this specific case, I was able to increase my performance by about 2X or 4X which got me within what I needed for my real time deadline.
p.s. I was working on a fixed point processor... and any floating point operations like sin/cos killed my performance.
Inline is ineffective when you use the pointer to function.
Inline is effective in one case: when you've got a performance problem, ran your profiler with real data, and found the function call overhead for some small functions to be significant.
Outside of that, I can't imagine why you'd use it.
That's right. Using inline for big functions increases compile time, and brings little extra performance to the application. Inline functions are used to tell the compiler that a function is to be included without a call, and such should be small code repeated many times. In other words: for big functions, the cost of making the call compared to the cost of the own function implementation is negligible.
I mainly use inline functions as typesafe macros. There's been talk about adding support for link-time optimizations to GCC for quite some time, especially since LLVM came along. I don't know how much of it actually has been implemented yet, though.
Personally I don't think you should ever inline, unless you have first run a profiler on your code and have proven that there is a significant bottleneck on that routine that can be partially alleviated by inlining.
This is yet another case of the Premature Optimization Knuth warned about.
Inline can be used for small and frequently used functions such as getter or setter method. For big functions it is not advisable to use inline as it increases the exe size.
Also for recursive functions, even if you make inline, the compiler will ignore it.
inline acts as a hint only.
Added only very recently. So works with only the latest standard compliant compilers.
Inline functions should be approximately 10 lines or less, give or take, depending on your compiler of choice.
You can tell your compiler that you want something inlined .. its up to the compiler to do so. There is no -force-inline option that I know of which the compiler can't ignore. That is why you should look at the assembler output and see if your compiler actually did inline the function, if not, why not? Many compilers just silently say 'screw you!' in that respect.
so if:
static inline unsigned int foo(const char *bar)
.. does not improve things over static int foo() its time to revisit your optimizations (and likely loops) or argue with your compiler. Take special care to argue with your compiler first, not the people who develop it.. or your just in store for lots of unpleasant reading when you open your inbox the next day.
Meanwhile, when making something (or attempting to make something) inline, does doing so actually justify the bloat? Do you really want that function expanded every time its called? Is the jump so costly?, your compiler is usually correct 9/10 times, check the intermediate output (or asm dumps).

Internal static variables in C, would you use them?

In C you can have external static variables that are viewable every where in the file, while internal static variables are only visible in the function but is persistent
For example:
#include <stdio.h>
void foo_bar( void )
{
static counter = 0;
printf("counter is %d\n", counter);
counter++;
}
int main( void )
{
foo_bar();
foo_bar();
foo_bar();
return 0;
}
the output will be
counter is 0
counter is 1
counter is 2
My question is why would you use an internal static variable? If you don't want your static variable visible in the rest of the file shouldn't the function really be in its own file then?
This confusion usually comes about because the static keyword serves two purposes.
When used at file level, it controls the visibility of its object outside the compilation unit, not the duration of the object (visibility and duration are layman's terms I use during educational sessions, the ISO standard uses different terms which you may want to learn eventually, but I've found they confuse most beginning students).
Objects created at file level already have their duration decided by virtue of the fact that they're at file level. The static keyword then just makes them invisible to the linker.
When used inside functions, it controls duration, not visibility. Visibility is already decided since it's inside the function - it can't be seen outside the function. The static keyword in this case, causes the object to be created at the same time as file level objects.
Note that, technically, a function level static may not necessarily come into existence until the function is first called (and that may make sense for C++ with its constructors) but every C implementation I've ever used creates its function level statics at the same time as file level objects.
Also, whilst I'm using the word "object", I don't mean it in the sense of C++ objects (since this is a C question). It's just because static can apply to variables or functions at file level and I need an all-encompassing word to describe that.
Function level statics are still used quite a bit - they can cause trouble in multi-threaded programs if that's not catered for but, provided you know what you're doing (or you're not threading), they're the best way to preserve state across multiple function calls while still providing for encapsulation.
Even with threading, there are tricks you can do in the function (such as allocation of thread specific data within the function) to make it workable without exposing the function internals unnecessarily.
The only other choices I can think of are global variables and passing a "state variable" to the function each time.
In both these cases, you expose the inner workings of the function to its clients and make the function dependent on the good behavior of the client (always a risky assumption).
They are used to implement tools like strtok, and they cause problems with reentrancy...
Think carefully before fooling around with this tool, but there are times when they are appropriate.
For example, in C++, it is used as one way to get singleton istances
SingletonObject& getInstance()
{
static SingletonObject o;
return o;
}
which is used to solve the initialization order problem (although it's not thread-safe).
Ad "shouldn't the function be in its own file"
Certainly not, that's nonsense. Much of the point of programming languages is to facilitate isolation and therefore reuse of code (local variables, procedures, structures etc. all do that) and this is just another way to do that.
BTW, as others pointed out, almost every argument against global variables applies to static variables too, because they are in fact globals. But there are many cases when it's ok to use globals, and people do.
I find it handy for one-time, delayed, initialization:
int GetMagic()
{
static int magicV= -1;
if(-1 == magicV)
{
//do expensive, one-time initialization
magicV = {something here}
}
return magicV;
}
As others have said, this isn't thread-safe during it's very first invocation, but sometimes you can get away with it :)
I think that people generally stay away from internal static variables. I know strtok() uses one, or something like it, and because of that is probably the most hated function in the C library.
Other languages like C# don't even support it. I think the idea used to be that it was there to provide some semblance of encapsulation (if you can call it that) before the time of OO languages.
Probably not terribly useful in C, but they are used in C++ to guarantee the initialisation of namespace scoped statics. In both C and C++ there are problemns with their use in multi-threaded applications.
I wouldn't want the existence of a static variable to force me to put the function into its own file. What if I have a number of similar functions, each with their own static counter, that I wanted to put into one file? There are enough decisions we have to make about where to put things, without needing one more constraint.
Some use cases for static variables:
you can use it for counters and you won't pollute the global namespace.
you can protect variables using a function that gets the value as a pointer and returns the internal static. This whay you can control how the value is assigned. (use NULL when you just want to get the value)
I've never heard this specific construct termed "internal static variable." A fitting label, I suppose.
Like any construct, it has to be used knowledgeably and responsibly. You must know the ramifications of using the construct.
It keeps the variable declared at the most local scope without having to create a separate file for the function. It also prevents global variable declaration.
For example -
char *GetTempFileName()
{
static int i;
char *fileName = new char[1024];
memset(fileName, 0x00, sizeof(char) * 1024);
sprintf(fileName, "Temp%.05d.tmp\n", ++i);
return fileName;
}
VB.NET supports the same construct.
Public Function GetTempFileName() As String
Static i As Integer = 0
i += 1
Return String.Format("Temp{0}", i.ToString("00000"))
End Function
One ramification of this is that these functions are not reentrant nor thread safe.
Not anymore. I've seen or heard the results of function local static variables in multithreaded land, and it isn't pretty.
In writing code for a microcontroller I would use a local static variable to hold the value of a sub-state for a particular function. For instance if I had an I2C handler that was called every time main() ran then it would have its own internal state held in a static local variable. Then every time it was called it would check what state it was in and process I/O accordingly (push bits onto output pins, pull up a line, etc).
All statics are persistent and unprotected from simultaneous access, much like globals, and for that reason must be used with caution and prudence. However, there are certainly times when they come in handy, and they don't necessarily merit being in their own file.
I've used one in a fatal error logging function that gets patched to my target's error interrupt vectors, eg. div-by-zero. When this function gets called, interrupts are disabled, so threading is a non-issue. But re-entrancy could still happen if I caused a new error while in the process of logging the first error, like if the error string formatter broke. In that case, I'd have to take more drastic action.
void errorLog(...)
{
static int reentrant = 0;
if(reentrant)
{
// We somehow caused an error while logging a previous error.
// Bail out immediately!
hardwareReset();
}
// Leave ourselves a breadcrumb so we know we're already logging.
reentrant = 1;
// Format the error and put it in the log.
....
// Error successfully logged, time to reset.
hardwareReset();
}
This approach is checking against a very unlikely event, and it's only safe because interrupts are disabled. However, on an embedded target, the rule is "never hang." This approach guarantees (within reason) that the hardware eventually gets reset, one way or the other.
A simple use for this is that a function can know how many times it has been called.

Resources