Consider the following code:
file_1.hpp:
typedef void (*func_ptr)(void);
func_ptr file1_get_function(void);
file1.cpp:
// file_1.cpp
#include "file_1.hpp"
static void some_func(void)
{
do_stuff();
}
func_ptr file1_get_function(void)
{
return some_func;
}
file2.cpp
#include "file1.hpp"
void file2_func(void)
{
func_ptr function_pointer_to_file1 = file1_get_function();
function_pointer_to_file1();
}
While I believe the above example is technically possible - to call a function with internal linkage only via a function pointer, is it bad practice to do so? Could there be some funky compiler optimizations that take place (auto inline, for instance) that would make this situation problematic?
There's no problem, this is fine. In fact , IMHO, it is a good practice which lets your function be called without polluting the space of externally visible symbols.
It would also be appropriate to use this technique in the context of a function lookup table, e.g. a calculator which passes in a string representing an operator name, and expects back a function pointer to the function for doing that operation.
The compiler/linker isn't allowed to make optimizations which break correct code and this is correct code.
Historical note: back in C89, externally visible symbols had to be unique on the first 6 characters; this was relaxed in C99 and also commonly by compiler extension.
In order for this to work, you have to expose some portion of it as external and that's the clue most compilers will need.
Is there a chance that there's a broken compiler out there that will make mincemeat of this strange practice because they didn't foresee someone doing it? I can't answer that.
I can only think of false reasons to want to do this though: Finger print hiding, which fails because you have to expose it in the function pointer decl, unless you are planning to cast your way around things, in which case the question is "how badly is this going to hurt".
The other reason would be facading callbacks - you have some super-sensitive static local function in module m and you now want to expose the functionality in another module for callback purposes, but you want to audit that so you want a facade:
static void voodoo_function() {
}
fnptr get_voodoo_function(const char* file, int line) {
// you tagged the question as C++, so C++ io it is.
std::cout << "requested voodoo function from " << file << ":" << line << "\n";
return voodoo_function;
}
...
// question tagged as c++, so I'm using c++ syntax
auto* fn = get_voodoo_function(__FILE__, __LINE__);
but that's not really helping much, you really want a wrapper around execution of the function.
At the end of the day, there is a much simpler way to expose a function pointer. Provide an accessor function.
static void voodoo_function() {}
void do_voodoo_function() {
// provide external access to voodoo
voodoo_function();
}
Because here you provide the compiler with an optimization opportunity - when you link, if you specify whole program optimization, it can detect that this is a facade that it can eliminate, because you let it worry about function pointers.
But is there a really compelling reason not just to remove the static from infront of voodoo_function other than not exposing the internal name for it? And if so, why is the internal name so precious that you would go to these lengths to hide that?
static void ban_account_if_user_is_ugly() {
...;
}
fnptr do_that_thing() {
ban_account_if_user_is_ugly();
}
vs
void do_that_thing() { // ban account if user is ugly
...
}
--- EDIT ---
Conversion. Your function pointer is int(*)(int) but your static function is unsigned int(*)(unsigned int) and you don't want to have to cast it.
Again: Just providing a facade function would solve the problem, and it will transform into a function pointer later. Converting it to a function pointer by hand can only be a stumbling block for the compiler's whole program optimization.
But if you're casting, lets consider this:
// v1
fnptr get_fn_ptr() {
// brute force cast because otherwise it's 'hassle'
return (fnptr)(static_fn);
}
int facade_fn(int i) {
auto ui = static_cast<unsigned int>(i);
auto result = static_fn(ui);
return static_cast<int>(result);
}
Ok unsigned to signed, not a big deal. And then someone comes along and changes what fnptr needs to be to void(int, float);. One of the above becomes a weird runtime crash and one becomes a compile error.
I'm implementing Lua in a game engine. All of the functions being exported to Lua have headers that start with luavoid, luaint or luabool just for quick reference of the expected parameters, and so I can see at a glance that this function is being exported.
#define luavoid(...) void
luavoid(std::string s) TextMsg()
{
std::string s;
ExtractLuaParams(1, s);
::TextMsg(s.c_str());
}
To actually export a function to Lua, they're added to a dictionary. On startup, the map is used to call lua_register.
std::unordered_map<std::string, ScriptCall> _callMap = {
{ "TextMsg", TextMsg },
...
}
There will be a lot of functions exported. Rather than have to maintain this map manually, I'd like to automate its creation.
My first instinct was something with macros at compile-time. I gave up on it initially and started writing a program to parse the code (as a pre-build event), since all the functions can be text-matched with the luaX macros. It would create a header file with the map automatically generated.
Then I went back to doing it at compile-time after figuring out a way to do it. I came up with this solution as an example before I finally implement it in the game:
using MapType = std::unordered_map<std::string, int>;
template <MapType& m>
struct MapMaker
{
static int MakePair(std::string s, int n)
{
m[s] = n;
return n;
}
};
#define StartMap(map) MapType map
#define AddMapItem(map, s, n) int map##s = MapMaker<map>::MakePair(#s, n)
StartMap(myMap);
AddMapItem(myMap, abc, 1);
AddMapItem(myMap, def, 2);
AddMapItem(myMap, ghi, 3);
void main()
{
for (auto& x : myMap)
{
std::cout << x.first.c_str() << "->" << x.second << std::endl;
}
}
It works.
My question is, how horrible is this and can it be improved? All I want in the end is a list mapping a a string to a function. Is there a better way to create a map or should I just go with the text-parsing method?
Be gentle(-ish). This is my first attempt at coding with templates like this. I assume this falls under template metaprogramming.
how horrible is this and can it be improved?
Somewhere between hideous and horrendous. (Some questions better left unasked.) And yes...
All I want in the end is a list mapping a a string to a function. Is there a better way to create a map or should I just go with the text-parsing method?
The simplest thing to do is:
#define ADDFN(FN) { #FN, FN }
std::unordered_map<std::string, ScriptCall> _callMap = {
ADDFN(TextMsg),
...
};
This uses the macros to automate the repetition in the string literal function names and identifiers - there's nothing further substantive added by your implementation.
That said, you could experiment with automating things further than your implementation, perhaps something like this:
#define LUAVOID(FN, ...) \
void FN(); \
static auto addFN ## __LINE__ = myMap.emplace(#FN, FN); \
void FN()
LUAVOID(TextMsg, string s)
{
...
}
See it running here.
The idea here is that the macro generates a function declaration so that it can register the function, then a definition afterwards. __LINE__ likely suffices for uniqueness of the identifiers - assuming you have one file doing this, and that your compiler substitutes a numeric literal (which all compilers I've used do, but I can't remember if the Standard mandates that). The emplace function has a non-void return type so can be used directly to insert to the map.
Be gentle(-ish). This is my first attempt at coding with templates like this.
Sorry.
I assume this falls under template metaprogramming.
It's arguable. Many C++ programmers (myself included) think of "metaprogramming" as involving more advanced template usage - such as variable-length lists of parameters, recursive instantiations, and specialisation - but many others consider all template usage to be "metaprogramming" since the templates provide instructions for how to create instantiations, which is technically sufficient to constitute metaprogramming.
I was just experimenting with C++. I was trying to write a small macro so that all the functions that I define are automatically stored in a map so that I can query, at run time, what functions exist and run them too. The code is as follows:
#include <map>
using namespace std;
typedef void (*funcPointer)();
map <char*, funcPointer> funcList;
#define Function(x) void x() { funcList[#x] = x;
#define End }
I was used funcPointer and End only for easy readability and implementation. Now, I can define a function as
Function(helloWorld)
cout << "Hello World";
End
Now, to read the function names as a list and run all the functions, I use the following code:
int main() {
//helloWorld();
for (map<char*, funcPointer>::iterator I = funcList.begin(); I != funcList.end(); I++) {
printf(I->first);
I->second();
}
getchar();
return 0;
}
The problem is, if I keep the first line of main() (helloWorld();) commented, the compiler doesn't compile the function and skips it for optimization, as according to the compiler, it is never used. So, the function list turns up empty. If, instead, I call the function once, every thing works perfectly, except that it prints "Hello World" twice. Also, I wrote the macro specifically so I do not have to do that.
So, is there any way that I can force the compiler to compile a function even if it is not used?
The problem is that the code to register the function is inside the function, so won't happen unless you call the function. You might instead register it by initialising a global variable, which will happen automatically before main begins. This might look something like
struct funcRegistration {
funcRegistration(char * name, funcPointer func) {funcList[name] = func;}
};
#define Function(x) \
void x(); \
funcRegistration x##_registration(#x, x); \
void x() {
The compiler compiles the function, however your map won't be populated unless its called.
Because funcList[#x] = x; comes inside the function block { } after macro expansion.
Is there a standard procedure for passing classes by value? In other words, if I do this:
struct Test
{
int a;
double b;
}
void DoSomething(Test t)
{
std::cout << t.a << std::endl;
std::cout << t.b << std::endl;
}
//...
Test myObj;
myObj.a = 5;
myObj.b = 10.5;
DoSomething(myObj);
Assuming standard packing and layout, does the standard provide any guarantees that the class will be sent and received in a consistent manner regardless of compiler?
Because I anticipate questions along the lines of "why do you want to do this?" or "this feels like an XY problem", here's (lengthy) context. I'm attempting to pass a class object back-and-forth between an EXE and a DLL compiled with different compilers, and it appears that the class object is not being read from the correct starting address. This problem evaporates if I pass the object by reference, however. (Bonus question - why would passing by reference work when passing by value would not? I was under the impression passing by value would copy the object and pass a reference to the copy. Clearly I'm misunderstanding something here.)
In general, ABI between different C++ compilers can vary in any way they see fit. The C++ standard does not mandate a given ABI.
However, C ABIs are extremely stable. One way to deal with this problem is to have header-only functions that translate your code into extern "C" functions, which are exported from your DLL. Inside your DLL the extern "C" functions then call a more conventional C++ interface.
For a concrete example,
struct Test;
// DLL exported:
extern "C" void Private_DoSomething_Exported( Test* );
// Interface:
namespace Interface {
inline void DoSomething( Test t ) { return Private_DoSomething_Exported(&t); }
};
// implementation. Using Test&& to make it clear that the reference is not an export parameter:
namespace Implementation {
void DoSomething( Test&&t ) {
std::cout << t.a << std::endl;
std::cout << t.b << std::endl;
}
}
void Private_DoSomething_Exported( Test* t ) {
Assert(t);
Implementation::DoSomething(std::move(*t));
}
This places the "most compatible" ABI (a pure "C" ABI) at the point where you export functions from a DLL. The client code calls Interface::DoSomething, which inline in the client code calls the "C" ABI (which doesn't even know the layout of the object), which then calls a C++ Implementation::DoSomething.
This is still not proof against every issue, because the layout of even POD structs could vary based on compilers (as a practical example, some compilers treat long as 32 bit on 64 bit machines, others treat long as 64 bits on 64 bit machines). Packing can also vary.
To reduce that impact, you'll first want to only use fixed size types from the C header files. You'll also want to examine the packing docs of both compilers.
Certain situations in my code, I end up invoking the function only if that function is defined, or else I should not. How can I achieve this?
like:
if (function 'sum' exists ) then invoke sum ()
Maybe the other way around to ask this question is how to determine if function is defined at runtime and if so, then invoke?
When you declare 'sum' you could declare it like:
#define SUM_EXISTS
int sum(std::vector<int>& addMeUp) {
...
}
Then when you come to use it you could go:
#ifdef SUM_EXISTS
int result = sum(x);
...
#endif
I'm guessing you're coming from a scripting language where things are all done at runtime. The main thing to remember with C++ is the two phases:
Compile time
Preprocessor runs
template code is turned into real source code
source code is turned in machine code
runtime
the machine code is run
So all the #define and things like that happen at compile time.
....
If you really wanted to do it all at runtime .. you might be interested in using some of the component architecture products out there.
Or maybe a plugin kind of architecture is what you're after.
Using GCC you can:
void func(int argc, char *argv[]) __attribute__((weak)); // weak declaration must always be present
// optional definition:
/*void func(int argc, char *argv[]) {
printf("FOUND THE FUNCTION\n");
for(int aa = 0; aa < argc; aa++){
printf("arg %d = %s \n", aa, argv[aa]);
}
}*/
int main(int argc, char *argv[]) {
if (func){
func(argc, argv);
} else {
printf("did not find the function\n");
}
}
If you uncomment func it will run it otherwise it will print "did not find the function\n".
While other replies are helpful advices (dlsym, function pointers, ...), you cannot compile C++ code referring to a function which does not exist. At minimum, the function has to be declared; if it is not, your code won't compile. If nothing (a compilation unit, some object file, some library) defines the function, the linker would complain (unless it is weak, see below).
But you should really explain why you are asking that. I can't guess, and there is some way to achieve your unstated goal.
Notice that dlsym often requires functions without name mangling, i.e. declared as extern "C".
If coding on Linux with GCC, you might also use the weak function attribute in declarations. The linker would then set undefined weak symbols to null.
addenda
If you are getting the function name from some input, you should be aware that only a subset of functions should be callable that way (if you call an arbitrary function without care, it will crash!) and you'll better explicitly construct that subset. You could then use a std::map, or dlsym (with each function in the subset declared extern "C"). Notice that dlopen with a NULL path gives a handle to the main program, which you should link with -rdynamic to have it work correctly.
You really want to call by their name only a suitably defined subset of functions. For instance, you probably don't want to call this way abort, exit, or fork.
NB. If you know dynamically the signature of the called function, you might want to use libffi to call it.
I suspect that the poster was actually looking for something more along the lines of SFINAE checking/dispatch. With C++ templates, can define to template functions, one which calls the desired function (if it exists) and one that does nothing (if the function does not exist). You can then make the first template depend on the desired function, such that the template is ill-formed when the function does not exist. This is valid because in C++ template substitution failure is not an error (SFINAE), so the compiler will just fall back to the second case (which for instance could do nothing).
See here for an excellent example: Is it possible to write a template to check for a function's existence?
use pointers to functions.
//initialize
typedef void (*PF)();
std::map<std::string, PF> defined_functions;
defined_functions["foo"]=&foo;
defined_functions["bar"]=&bar;
//if defined, invoke it
if(defined_functions.find("foo") != defined_functions.end())
{
defined_functions["foo"]();
}
If you know what library the function you'd like to call is in, then you can use dlsym() and dlerror() to find out whether or not it's there, and what the pointer to the function is.
Edit: I probably wouldn't actually use this approach - instead I would recommend Matiu's solution, as I think it's much better practice. However, dlsym() isn't very well known, so I thought I'd point it out.
You can use #pragma weak for the compilers that support it (see the weak symbol wikipedia entry).
This example and comment is from The Inside Story on Shared Libraries and Dynamic Loading:
#pragma weak debug
extern void debug(void);
void (*debugfunc)(void) = debug;
int main() {
printf(“Hello World\n”);
if (debugfunc) (*debugfunc)();
}
you can use the weak pragma to force the linker to ignore unresolved
symbols [..] the program compiles and links whether or not debug()
is actually defined in any object file. When the symbol remains
undefined, the linker usually replaces its value with 0. So, this
technique can be a useful way for a program to invoke optional code
that does not require recompiling the entire application.
So another way, if you're using c++11 would be to use functors:
You'll need to put this at the start of your file:
#include <functional>
The type of a functor is declared in this format:
std::function< return_type (param1_type, param2_type) >
You could add a variable that holds a functor for sum like this:
std::function<int(const std::vector<int>&)> sum;
To make things easy, let shorten the param type:
using Numbers = const std::vectorn<int>&;
Then you could fill in the functor var with any one of:
A lambda:
sum = [](Numbers x) { return std::accumulate(x.cbegin(), x.cend(), 0); } // std::accumulate comes from #include <numeric>
A function pointer:
int myFunc(Numbers nums) {
int result = 0;
for (int i : nums)
result += i;
return result;
}
sum = &myFunc;
Something that 'bind' has created:
struct Adder {
int startNumber = 6;
int doAdding(Numbers nums) {
int result = 0;
for (int i : nums)
result += i;
return result;
}
};
...
Adder myAdder{2}; // Make an adder that starts at two
sum = std::bind(&Adder::doAdding, myAdder);
Then finally to use it, it's a simple if statement:
if (sum)
return sum(x);
In summary, functors are the new pointer to a function, however they're more versatile. May actually be inlined if the compiler is sure enough, but generally are the same as a function pointer.
When combined with std::bind and lambda's they're quite superior to old style C function pointers.
But remember they work in c++11 and above environments. (Not in C or C++03).
In C++, a modified version of the trick for checking if a member exists should give you what you're looking for, at compile time instead of runtime:
#include <iostream>
#include <type_traits>
namespace
{
template <class T, template <class...> class Test>
struct exists
{
template<class U>
static std::true_type check(Test<U>*);
template<class U>
static std::false_type check(...);
static constexpr bool value = decltype(check<T>(0))::value;
};
template<class U, class = decltype(sum(std::declval<U>(), std::declval<U>()))>
struct sum_test{};
template <class T>
void validate_sum()
{
if constexpr (exists<T, sum_test>::value)
{
std::cout << "sum exists for type " << typeid(T).name() << '\n';
}
else
{
std::cout << "sum does not exist for type " << typeid(T).name() << '\n';
}
}
class A {};
class B {};
void sum(const A& l, const A& r); // we only need to declare the function, not define it
}
int main(int, const char**)
{
validate_sum<A>();
validate_sum<B>();
}
Here's the output using clang:
sum exists for type N12_GLOBAL__N_11AE
sum does not exist for type N12_GLOBAL__N_11BE
I should point out that weird things happened when I used an int instead of A (sum() has to be declared before sum_test for the exists to work, so maybe exists isn't the right name for this). Some kind of template expansion that didn't seem to cause problems when I used A. Gonna guess it's ADL-related.
This answer is for global functions, as a complement to the other answers on testing methods. This answer only applies to global functions.
First, provide a fallback dummy function in a separate namespace. Then determine the return type of the function-call, inside a template parameter. According to the return-type, determine if this is the fallback function or the wanted function.
If you are forbidden to add anything in the namespace of the function, such as the case for std::, then you should use ADL to find the right function in the test.
For example, std::reduce() is part of c++17, but early gcc compilers, which should support c++17, don't define std::reduce(). The following code can detect at compile-time whether or not std::reduce is declared. See it work correctly in both cases, in compile explorer.
#include <numeric>
namespace fallback
{
// fallback
std::false_type reduce(...) { return {}; }
// Depending on
// std::recuce(Iter from, Iter to) -> decltype(*from)
// we know that a call to std::reduce(T*, T*) returns T
template <typename T, typename Ret = decltype(reduce(std::declval<T*>(), std::declval<T*>()))>
using return_of_reduce = Ret;
// Note that due to ADL, std::reduce is called although we don't explicitly call std::reduce().
// This is critical, since we are not allowed to define any of the above inside std::
}
using has_reduce = fallback::return_of_reduce<std::true_type>;
// using has_sum = std::conditional_t<std::is_same_v<fallback::return_of_sum<std::true_type>,
// std::false_type>,
// std::false_type,
// std::true_type>;
#include <iterator>
int main()
{
if constexpr (has_reduce::value)
{
// must have those, so that the compile will find the fallback
// function if the correct one is undefined (even if it never
// generates this code).
using namespace std;
using namespace fallback;
int values[] = {1,2,3};
return reduce(std::begin(values), std::end(values));
}
return -1;
}
In cases, unlike the above example, when you can't control the return-type, you can use other methods, such as std::is_same and std::contitional.
For example, assume you want to test if function int sum(int, int) is declared in the current compilation unit. Create, in a similar fashion, test_sum_ns::return_of_sum. If the function exists, it will be int and std::false_type otherwise (or any other special type you like).
using has_sum = std::conditional_t<std::is_same_v<test_sum_ns::return_of_sum,
std::false_type>,
std::false_type,
std::true_type>;
Then you can use that type:
if constexpr (has_sum::value)
{
int result;
{
using namespace fallback; // limit this only to the call, if possible.
result = sum(1,2);
}
std::cout << "sum(1,2) = " << result << '\n';
}
NOTE: You must have to have using namespace, otherwise the compiler will not find the fallback function inside the if constexpr and will complain. In general, you should avoid using namespace since future changes in the symbols inside the namespace may break your code. In this case there is no other way around it, so at least limit it to the smallest scope possible, as in the above example