Force implementation/definition of function declaration - c++

Suppose i have a header that should work in both C and C++.
This header contains some functions that the program must define, such as:
EXPORTED void * STD_API GetSymbol(CProject * p, char * s);
How can i ensure that these functions are actually defined somewhere? Even if the project actually compiles without, it is invalid because these functions will be looked up at runtime by another module (it is to be compiled as a module/dll/dylib/whatever).
The only thing i can think of is to use the definition somewhere, perhaps in a function call. However, that requires a function implementation in the header, which we all know will lead to multiple defintions.
In C++ you can probably get away with a hack like this:
#ifdef __cplusplus
static inline void _impcheck()
{
assert(0 && "_impcheck called.");
GetSymbol(NULL, NULL);
}
#endif
(because of how inline modifer allows multiple definitions). But how about c?

Firstly, C has static and inline too.
Second, how about...
documenting that the functions are to be implemented by the user?
checking at runtime the availability of the functions and reporting an error/throwing an exception when one can't be found? dlsym() (I assume you are using the dlopen() API, is that true?) will return a null pointer when it can't find a symbol.
If you really want a link-time failure, then you can try using the functions (call them, or assign their names to volatile function pointers if you don't want side effects to be performed prematurely, etc.)

C allows exactly the same static inline function. But the compiler will probably optimize it away because your assert gets triggered so that following code is marked unreachable.

Related

C++ inline function inside a static class or namespace

I have a very small function that could be a macro, but anyway, I thought inline function would do exactly the same.
But nah, when I mark a function in a namespace as inline it is not visible by any other file that includes my module.
I tried it both with a static class and a namespace. No error when the function is declared or implemented, error in each reference, exactly as if the function was static.
Is there a way to have an inline function available for other files that include the file where my function is declared?
Let's say I have a module that handles some hardware stuff, and one of the functions is something like this:
bool getState(HWFlag flag)
{
return (State & flag) > 0
}
I know, it can be written as macro, but logically the function is a part of a bigger module. I would certainly used a macro in C, but it's C++ so I thought there might be a better way. But well, I obviously don't understand how it works.
BTW, shouldn't the compiler just inline it anyway so I shouldn't even care?
BTW2: Is making the module that mainly talks with C code a class with only static method a bad idea or does it have any use? That's how I made it initially but later decided to just make it a namespace to simplify the syntax a little. But in any case, if I use the inline keyword the function becomes private.
An inline function should be defined identically in every translation unit that uses it. So you should define your inline function exactly as you would a macro--in a header file that gets included by all of the files that need it.

Why `-fvisibility-inlines-hidden` is not the default?

I am asking to see whether my understandings are correct.
inline is a suggestion to C++ compiler for substituting a function whenever it sees better, therefore calling a procedure flagged as inlined from outside of a library shouldn't be reliable and they logically should be hidden by default, preventing others to call them as an update to a compiler or codebase can be change the decision (thus removal of the inlined function and ABI breakage?).
However it seems that is not the default setting and -fvisibility-inlines-hidden should be set to make that happen. I am asking here why that is the case? Does not setting that has any real use case and it is there just because legacy reasons?
they logically should be hidden by default
C++ requires all functions (including inline functions) to have the same address in all translation units. Local statics should also be shared among all translation units. Making inline functions hidden violates those requirements if program is built as multiple shared objects (.so files).
Inline functions should have public visibility so that dynamic linker could choose one definition from all existing ones at runtime.
GCC wiki mentions this:
-fvisibility-inlines-hidden can be used with no source alterations, unless you need to override it for inlines where address identity is important either for the function itself or any function local static data.
Consider following example. Executable source:
// main.cpp
#include <cstdio>
struct A { };
inline A &foo()
{
static A a;
return a;
}
int main()
{
void *p = &foo();
std::printf("main() - %p\n", p);
}
Shared object source:
#include <cstdio>
struct A { };
inline A &foo()
{
static A a;
return a;
}
static __attribute__((constructor)) void init()
{
void *p = &foo();
std::printf("main() - %p\n", p);
}
If you build both and link executable against this shared object, you can see that foo always returns the same address in both translation units.
Now if you add __attribute__((visibility("hidden"))) to those inline functions, then you will see that address is different in different translation units.
This is not what some C++ program might expect.
Most people today think that inline has nothing to do with actual function inlining. This is not exactly true. ELF targets try to make dynamic linking transparent e.g. program should behave identically if it is build as a single executable or as multiple shared objects.
To make it possible ELF requires all functions with public visibility to be called though GOT or through PLT as if it is "imported" function. This is required so that every function could be overriden by another library (or executable itself). This also forbids inlining for all public non-inline functions (see section 3.5.5 here which shows that public function call in PIC should be made through PLT).
Code inlining for public inline functions is possible exactly because inline allows program behavior to be undefined when multiple definitions of inline function are not equivalent.
Interesting note: Clang violates this ELF requirement and is able to inline public functions on ELF targets anyway. GCC can do the same with -fno-semantic-interposition flag.
inline is a suggestion to C++ compiler for substituting a function whenever it sees better
No. This was originally the case, in perhaps the late 90s, but has not been true for a long time.
See this answer for a good explanation.
therefore calling a procedure flagged as inlined from outside of a library shouldn't be reliable
your initial assumption is already wrong, so the therefore is proceeding from a false premise
even if the compiler does inline a call (which it may do with or without the inline keyword), this is done at a specific call site. Inlining isn't something that happens to a function, which must always be emitted as usual, but to a function call.
It's entirely possible for the compiler to inline some calls to a function and not others, depending on its opinion of what will produce the best code at the call site.
Now, it's not clear what problem you believe inline causes in libraries, so it's hard to address that directly.
inline is a suggestion to C++ compiler for substituting a function whenever it sees better, therefore calling a procedure flagged as inlined from outside of a library shouldn't be reliable and they logically should be hidden by default
The compiler can still decide to inline some calls and leave some of them non-inlined. In this case you would get several copy of the inlined function in all the libraries you are linking together.
Moreover the standard somewhat requires that &foo to be the same address everywhere in your program, although the standard does not say anything about DSO/DLLs, so the compilers have some freedom in those regards (in fact, MSVC follows the opposite approach of leaving everything hidden by default).
However it seems that is not the default setting and -fvisibility-inlines-hidden should be set to make that happen.
Despite the name, -fvisibility-inlines-hidden only affects inlined class member functions. For everything else, -fvisibility=hidden should be sufficient.
Does not setting that has any real use case and it is there just because legacy reasons?
Yes. IIRC that flag was implemented in GCC 3.2 (or close enough); making it default would break a lot of legacy code.

Using an inline function for an API

I want to create an API which, on the call of a function, such as getCPUusage(), redirects to a getCPUusage() function for Windows or Linux.
So I'm using a glue file api.h :
getCPUusage() {
#ifdef WIN32
getCPUusage_windows();
#endif
#ifdef __gnu_linux__
getCPUusage_linux();
#endif
}
So I wonder if using inline would be a better solution, since with what I have, the call will be bigger.
My question is the following : is it better to use inlined function for every call in this situation ?
It depends on use-case of your program. If consumer is still c++ - then inline has a sense.
But just assume that you would like to reuse it inside C, Pascal, Java ... in this case inline is not a case. Caller must export someway stable name over lib, but not from header file.
Lib for linux is rather transparent, while on Windows you need apply __dllexport keyword - that is not applicable to inline
The answer is: yes, it is indeed more efficient, but probably not worthwhile:
If you're putting these functions in a class, it is not required that you write down the "inline" keyword in your situation, because you only have a header file (You don't have any cpp-files - according to your description). Functions that are implemented inside the class definition (in the header file) will be automatically seen as inline functions by the compiler. Note however that this is only a "hint" to the compiler. The compiler may still decide to make your function non-inline if that is found to be (by the compiler) more efficient. For small functions like yours, it will most likely produce actual inline functions.
If you're not putting these functions in a class, I don't think you should bother adding inline either, as (as said above) it's only a "hint" and even without those "hints", modern compilers will figure out what functions to inline anyway. Humans are much more likely to be wrong about these things then the compiler anyway.

Static libraries. Importing and exporting inline functions

This question arose while I was implementing my static library.
I want to check my guess and gain information on using inline functions in static libs.
My guess is that an iplementator of a static lib can not export an inline function in his library
Due to the inline statement is
implemented by a compiler(it is up to the compiler whether to make
the function inline) by placing low level commands representing
operations in the function body to the code segment so that
operations won't be placed in the tables of export/import and
therefore can't be processed by linker and therefore can't be
included by librarian to the code of application to which static lib
is attached. Is my logic right?
I guess that importing function as inline is allowed but I wonder how it is implemented, because it is compiler`s
responsibility but on the linkage state there is only librarian, so
that means that it must undertake some actions in order to make
function inline.
Yes, inline functions are typically placed in a header, so the function body is directly visible to the compiler everywhere the function is used. This lets the compiler evaluate whether to generate inline code for the function in any particular instance.
This basically doesn't arise -- "An inline function shall be defined in every translation unit in which it is odr-used." (ยง3.2/3). That means if the compiler is going to generate the function inline, what goes into the library is object code that includes inline expansion of the code for that function. Since it's possible that function may not be expanded inline at every use, there will also typically be a definition of the function in the library, but that definition will be used (at least primarily) like a normal function, not expanded inline.
Linkers can also generate code though. Regardless of whether a function is or isn't an inline function by the language standard, and is defined in the same or a different translation unit from the one where it's used, the linker may be able to generate inline code for it anyway.
To make a long story short, the inline keyword has little or no effect on a typical compiler as far as whether a function's code will be generated inline or not. The main (if not sole) effect is that it changes the one-definition rule -- being inline means that multiple (identical) definitions of the same function can exist without causing a problem.
Do you understand the keyword inline - you could equally use replace.
An inline function enables the compile if so choosing to replace the function call with the actual code - nothing to export/import. It is defined in the header file. Anything that uses the object code will require that header code and thus the compiler will replace the function call with the actual code.
On Visual C++ you can use Microsoft specific behavior, and export/import inline functions with __declspec(dllexport) inline or extern inline. Note that this is Microsoft specific behavior, if you target anything but Windows and are not concerned at all with portability, you could consider it.

Why main() in C++ cannot be inlined?

I was reading the C++ FAQs and I noticed one sentence.
main() cannot be inline.
Why is this?
In C++ it is not legal to call the main function in your code, so there'd be no way it could ever be inlined.
Because the standard says so:
[2003: 3.6.1/3]:
The function main shall not be used (3.2) within a program. The
linkage (3.5) of main is implementation-defined. A program that
declares main to be inline or static is ill-formed. The name main is
not otherwise reserved. [Example: member functions, classes, and
enumerations can be called main, as can entities in other namespaces.
]
And why does it say so? Because it's trying to leave as much about the implementation of main to the individual .. well, implementation .. as is possible, and doesn't want to limit implementations by requiring that inline be valid here when it arguably has no practical benefit.
My friend on the committee confirmed this:
There's no reason why an inline main() wouldn't work, per se. [..] I could have a C++ interpreter that can invoke inlined main(). [..] [But] inline/static main() are forbidden in order to hopefully avoid confusion. I find it hard to imagine that the rationale would be anything additional to what's already been said in [this Q&A].
BTW, don't confuse the inline hint keyword with actually inlining functions. You can mark a function inline and it may not be physically inlined.
So, even if it were true that main "cannot be inlined" (and strictly speaking it is not true, though inlining main would be rather awkward and pointless as explained in other answers), it could theoretically still support the inline hint keyword just fine.
It doesn't for the reason stated above, and in litb's answer: it would complicate matters for no real benefit.
The C runtime library needs to find this symbol in order to "know" which function to run.
You cannot directly call main() (it's forbidden in c++), so there is no point of inlining it.
Usually main() is called from systems init() function. Thus, it is needed that there can be exactly one definition for main().
Now, if we can inline the main() function and include in a header file then, for every translation unit there will be different definition for main(). Which is not allowed. You can declare main() in a namespace and inline it. But not the global main().
firstly you must understand how work function with inline
example:
inline void f() {
int a = 3;
a += 3;
cout << a;
}
int main() {
f();
return 0;
}
will look like to the compiler as:
int main() {
int a = 3;
a += 3;
cout << a;
return 0;
}
looking at this example, how do you want to make main inline? This method is inline immediately.
The C++ standard says that the main function cannot be inlined, per #Tomalak Geret'kal's reply. This response discusses possibility of inlining of the main function, were the restriction in the Standard removed.
Definition of Inline
The inline keyword is a suggestion to the compiler to paste the contents of the function in-situ. One intent is to remove the overhead present in calling and returning from a function (subroutine).
An important situation of inlining is the case where there is a pointer to the function. In this case, there must be at least one static copy of the function. In this case, the linker can resolve "external linkages" of the inlined function because there is one static version.
Important to note that the compiler and linker determine whether or not to paste the contents or calls a single instance of the function.
Also of note, functions that are not tagged by the programmer may also be inlined by the compiler.
Inlining the main function
Since there is only one invocation of main allowed, how it is linked is up to the compiler. Single instances of inline functions are allowed by the Standard. The compiler is allowed to convert an inlined function into a function call to a single instance. So the compiler would ignore an inline suggestion for the main function.
The compiler and linker would have to insure that only one instance of the inlined main function exists. This where the tricky part comes in, especially with external linkage. One process for ensuring one instance is to leave information that a translation has a 'main' function whether or not it is inlined. Note: When a call to an inline function is made, the compiler is allowed to remove the function from the symbol tables for external linkage, since the idea is that the function won't be called by external functions.
Summary
Technically, there is nothing preventing the main function from being inlined. The machinery already exists for converting inlined functions into single instances and for identifying multiple instances of a function. When there is a pointer to an inlined function, a single instance of a function is made, so it has an address. This machinery would satisfy the Run-Time Library requirements for main having an address. In the case of inline for the main function, it would be ignored but there should not be any reason to prevent this syntax (except confusing people). After all, there are already syntax cases that are redundant, such as declaring a parameter that is passed by value (copy) as const.
"That's just my opinion, I could be wrong." -- Dennis Miller, comedian.
Others have remarked that an invocation of main can not meaningfully be inlined at the machine code level. That's rubbish. It would require a bit of help from the linker (like global optimization) or else per-application recompilation of a bit of the runtime library, but it's quite doable, no technical problem here.
However, the hinting effect of inline, that calls should preferably be inlined, is irrelevant for a function that is only called once and at the top level of control, as main is.
The only guaranteed effect of inline is to allow an external linkage function to be defined (identically) in two or more translation units, i.e. affecting the One Definition Rule.
As a practical matter this allows the definition to be placed in a header file, and placing it in a header file is a also practically necessary to guarantee identical definitions.
That does not make sense for main, so there is no reason for main to be inline.
You can only define main once. So putting inline would not serve any purpose - inline only has a significant purpose on functions you can define multiple times in a program (all definitions will be treated as if there were only one definition and all definitions are required to be the same).
Because inline functions can be defined multiple times in a program, and inline also serves the purpose of making calls to an inline-marked function as fast as possible, the Standard requires inline functions to be defined in every translation unit in which it is used. So compilers will usually throw away the definition of a function if it is inline and the function wasn't used by the code in the current translation unit. To do that for main would be entirely wrong, which goes to show that inline and the semantics main has is entirely incompatible.
Note that the question in your title "Why main() in C++ cannot be inlined?" and the statement you quote out of the Standard concern different things. You are asking whether the function can be inlined, which commonly is understood to insert the code of a called function completely or partially into the calling function. Just marking a function inline doesn't imply inlining that function at all. It's entirely the compiler's decision, and of course if you never call main (and you cannot do so) then there is nothing to be inlined.
If you linked statically to the CRT and enabled some link-time compilation-inlining (like MSVC has) it might be possible to inline it.
But it doesn't really make sense. It will be called once and that function call-overhead is practically naught compared to everything else that is done before the first line in main executes.
...
Aaand, it is an easy way to force the symbol to appear only once in your executable. :)
There are a number of basic reasons. Basically, main is called from
the basic initialization routine of the runtime, and only from there.
That code was (obviously) compiled without knowing that your main was
inlined. Modern compiler technology is capable of inlining across
module boundaries, but it's an advanced feature, not supported by many
older compilers. And of course, the benefits of inlining are only
present when a function is called very frequently; by definition, main
will be called exactly once, no more, no less.
I see the standard says so, but the real practical answer would be as simple as stating that the runtime added to every C and C++ program has to call to some point in the executable. That function should have an external symbol (and address when running) so that the linker can find it to be called at the beginning of execution. Hence you cannot declare it as inline, because inlined the compiler wouldn't generate an external symbol for it.
Since its the main() function, which starts the execution, when the code gets compiled to binary, everything is in the main() itself. so you can say, it already inlined!
And yes, its illegal to use inline for your C++ program, that's more about a syntax!
For most combinations of compiler/archetecture, the main() function in the source becomes a reasonably normal function in the final binary. This is only because it's convenient on those archetectures, not because the standard says it must be so.
On memory constrained archetectures, many compilers, ones which produce a flat binary (like intex hex format) instead of a dynamic linker friendly container (like elf or xcoff), optimize all of the boilerplate away, since it would just be bloat. Some architectures don't support function calls at all (only a limited subset of C++ is possible on these platforms.)
In order to support the widest variety of such architectures and build environments, the standard elects keep the semantics of main() as open as possible, so that the compiler can do what's right for the widest variety of platforms. That means that many features available in the language as a whole cannot apply to the startup and shutdown of the application itself.
If you need something like an inline main() (or reentrancy, or any fancy feature) you can of course call the main function something else:
inline int myMain(int argc, char **argv) { /* whatever */ }
int main(int argc, char **argv) { return myMain(argc, argv); }
Inline functions are having static scope by-default. It means if we declare main() as inline, it's scope will be limited to the file where it is defined. Yet, the C start-up library (provided by compiler vendor) needs 'main' to be a global symbol. There are some compilers that allow to modify entry point function (e.g. main) using linker flags.
inline functions don't usually have an address, so there is no portable way to call main, main() needs an address on which the init code can jump into. Inlined functions are meant to be stuck into the calling function, if main is inlined, it should be inlined into the init code of the program, which is not portable either.
operating system loads binary data to memory; looks for entry point (the 'main' symbol in c/c++); makes far jump to the addres of the entry point label. Operating system does not know anything about main function in your code until the program is not loaded.