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
Related
I am working on a problem that requires me to return different return-types based on my function parameter values that I provide.
I want to do something like this --
In the code below, doSomething() is an already existing function (used by a lot of clients) which takes mode as a function parameter, and returns std::list<ReturnType> already.
Based on the mode value, I had to create another sub-functionality which returns a shared_future<std::list<ReturnType>>.
How can I change this code so that it can return one of the two return types based on the mode value?
Note: ReturnType is a template typename which we are using for the entire class.
Code:
std::shared_future<std::list<ReturnType> > futureValue() {
return functionReturningSharedFuture();
}
std::list<ReturnType> listValue() {
return functionReturningList();
}
std::list<ReturnType> doSomething(int mode) {
if(mode == 1){
// new functionality that I added
return futureValue(); // This (obviously) errors out as of now
}
else{
// already there previously
return listValue();
}
}
int main() {
doSomething(1);
return 0;
}
How can I change this code so that it can return one of the two return types based on the mode value?
Constraints and Issues:
This issue could've been easily solved by function overloading if we provide an extra function parameter (like a true value), but that extra argument is not useful, since we are already using mode. Also, it isn't considered a good design to add variables which have almost no use.
One of the major constraints is that there are clients who are already using this doSomething() expect a std::list<ReturnType>, and so I cannot return boost::any or std::variant or anything similar.
I tried using std::enable_if, but it wasn't working out since we are getting the mode value at runtime.
We can't use template metaprogramming since that would change the way our function is being called on the client-side. Something that we can't afford to do.
Thank you.
This cannot be done.
You can only have one function with a given signature. If you have calling code that already expects this to return a std::list<ReturnType>, that's it; you're done.
If you could guarantee that all existing calling code looks like
auto l = obj.doSomething(1);
then you could potentially change the return type to something which would look like a std::list to any calling code. But if there's any calling code that looks like
std::list<ReturnType> l = obj.doSomething(1);
then that's off the table.
You probably need to rethink your design here.
From the example main, I see doSomething(1);, so maybe at the call site the value of the parameter mode is always known at compile-time. In this case, one option is that you make doSomething a template<int mode> function. I'm thinking about something like this:
#include <iostream>
#include <list>
#include <vector>
// assuming you cannot change this (actually you have changed it in you example, ...)
std::list<int> doSomething(int mode) {
std::cout << "already existing function\n";
return std::list<int>{1,2,3};
}
// then you can put this too
template<int N>
auto doSomething();
template<>
auto doSomething<10>() {
std::cout << "new function\n";
return std::vector<int>{1,2,3};
}
int main() {
auto x = doSomething(3);
auto y = doSomething<10>();
}
Probably another option would be to use a if constexpr intead of if and an auto/decltype(auto) return type in doSomething, but I haven't tried it.
std::experimental::source_location will probably be added to the C++ standard at some point. I'm wondering if it possible to get the location information into the compile-time realm. Essentially, I want a function that returns different types when called from different source locations. Something like this, although it doesn't compile because the location object isn't constexpr as it's a function argument:
#include <experimental/source_location>
using namespace std::experimental;
constexpr auto line (const source_location& location = source_location::current())
{
return std::integral_constant<int, location.line()>{};
}
int main()
{
constexpr auto ll = line();
std::cout << ll.value << '\n';
}
This doesn't compile, with a message about
expansion of [...] is not a constant expression
regarding the return std::integral_constant<int, location.line()>{} line. What good it is to have the methods of source_location be constexpr if I can't use them?
As Justin pointed the issue with your code is that function argument are not constexpr but the problem of using source_location in a constexpr function in a more useful way is mentioned in the constexpr! functions proposal which says:
The "Library Fundamentals v. 2" TS contains a "magic" source_location
class get to information similar to the FILE and LINE macros
and the func variable (see N4529 for the current draft, and N4129
for some design notes). Unfortunately, because the "value" of a
source_location is frozen at the point source_location::current() is
invoked, composing code making use of this magic class is tricky:
Typically, a function wanting to track its point of invocation has to
add a defaulted parameter as follows:
void my_log_function(char const *msg,
source_location src_loc
= source_location::current()) {
// ...
}
This idiom ensure that the value of the source_location::current()
invocation is sampled where my_log_function is called instead of where
it is defined.
Immediate (i.e., constexpr!) functions, however, create a clean
separation between the compilation process and the constexpr
evaluation process (see also P0992). Thus, we can make
source_location::current() an immediate function, and wrap it as
needed in other immediate functions: The value produced will
correspond to the source location of the "root" immediate function
call. For example:
constexpr! src_line() {
return source_location::current().line();
}
void some_code() {
std::cout << src_line() << '\n'; // This line number is output.
}
So this is currently an open problem.
C++17 has a new attribute, [[nodiscard]].
Suppose, that I have a Result struct, which has this attribute:
struct [[nodiscard]] Result {
};
Now, if I call a function which returns Result, I got a warning if I don't check the returned Result:
Result someFunction();
int main() {
someFunction(); // warning here, as I don't check someFunction's return value
}
This program generates:
warning: ignoring return value of function declared with 'nodiscard'
attribute [-Wunused-result]
So far, so good. Now suppose, that I have a special function, for which I still want to return Result, but I don't want this warning generated, if the check is omitted:
Result someNonCriticalFunction();
int main() {
someNonCriticalFunction(); // I don't want to generate a warning here
}
It is because, someNonCriticalFunction() does something non-critical (for example, something like printf - I bet that no-one checks printf's return value all the time); most cases, I don't care if it fails. But I still want it to return Result, as in some rare cases, I do need its Result.
Is it possible to do this somehow?
Possible solutions which I don't like:
I would not like calling it as (void)someNonCriticalFunction(), because this function is called a lot of times, it is awkward
creating a wrapper around someNonCriticalFunction(), which calls (void)someNonCriticalFunction(): I don't want to have a differently named function just because of this
removing [[nodiscard]] from Result, and add it to every function which returns Result
Why not make use of std::ignore from the <tuple> header—that would make the discard explicit:
[[nodiscard]] int MyFunction() { return 42; }
int main()
{
std::ignore = MyFunction();
return 0;
}
Compiler explorer of this code snippet: https://godbolt.org/z/eGPsjajz8
CPP Reference for std::ignore: https://en.cppreference.com/w/cpp/utility/tuple/ignore
I recommend the option you ruled out:
"removing [[nodiscard]] from Result, and add it to every function which returns Result."
But since you don't seem happy with it, here's another solution, using bog-standard inheritance:
struct [[nodiscard]] Result {
};
struct DiscardableResult: public Result {
};
For the functions where you can discard the result, use DiscardableResult as return type:
Result func1();
DiscardableResult func2();
func1(); // will warn
func2(); // will not warn
They say that every problem in computer science can be solved by adding another layer of indirection:
template <bool nodiscard=true>
struct Result;
template <>
struct Result<false> {
// the actual implementation
};
template <>
struct [[nodiscard]] Result<true>
: Result<false>
{
using Result<false>::Result;
};
This is effectively making Result conditionally [[nodiscard]], which allows:
Result<true> someFunction();
Result<false> someNonCriticalFunction();
int main() {
someFunction(); // warning here
someNonCriticalFunction(); // no warning here
}
Although really, this is identical to:
removing [[nodiscard]] from Result, and add it to every function which returns Result
which gets my vote to begin with.
You can suppress the warning with another C++17 attribute, namely [[maybe_unused]]
[[nodiscard]] int MyFunction() { return 42; }
int main()
{
[[maybe_unused]] auto v = MyFunction();
return 0;
}
This way you also avoid the confusing dependency to std::tuple which comes with std::ignore, even CppCoreGuidelines is openly recommending to use std::ignore for ignoring [[nodiscard]] values:
Never cast to (void) to ignore a [[nodiscard]]return value. If you
deliberately want to discard such a result, first think hard about
whether that is really a good idea (there is usually a good reason the
author of the function or of the return type used [[nodiscard]] in the
first place). If you still think it's appropriate and your code
reviewer agrees, use std::ignore = to turn off the warning which is
simple, portable, and easy to grep.
Looking at C++ reference, officially std::ignore is only specified to be used in std::tie when unpacking tuples.
While the behavior of std::ignore outside of std::tie is not formally
specified, some code guides recommend using std::ignore to avoid
warnings from unused return values of [[nodiscard]] functions.
cast the result to a (void *).
int main()
{
(void *)someFunction(); //Warning will be gone.
}
This way you "used" your result as far as the compiler is concerned. Great for when you are using a library where nodiscard has been used and you really don't care to know the result.
I have a function declared as int __stdcall MyFunction(int param, int param); and I need to get a type of the pointer to the function in a macro or a template when the name is passed as a parameter.
Is this possible in C++ or do I have to rewrite the function signature myself?
You can make a type alias for a function pointer (to which it decays, or which is returned by the address-of operator) the following way:
#include <iostream>
int MyFunction(int param, int param1)
{
std::cout << param << " " << param1 << std::endl;
return 0;
}
using Myfunction_ptr_t = std::decay<decltype(MyFunction)>::type;
// or using Myfunction_ptr_t = decltype(&MyFunction);
// or using Myfunction_ptr_t = decltype(MyFunction) *;
int main()
{
Myfunction_ptr_t Myfunction_ptr = MyFunction;
Myfunction_ptr(1, 2);
}
This example should rather use the auto specifier (since C++ 11):
auto Myfunction_ptr = MyFunction;
but that won't help in non-deducible context.
Function pointer behaves like every other pointer. It is a memory address which points to some entity (function code in this case). You can save these pointers somewhere and then fetch them in any convenient for your situation way.
For example you can create static map of std::string vs fun. pointer pairs:
static std::map<std::string, PTR_TYPE> funMap;
After that save pointers to this map and retreive them when needed.
If you don't have pointer yet, probably you speak about exported functions from libraries. In this case look at ldd for *nix-based or somethig simialar for other platform. You will need to search for runtime linker information and find fnction by it's name.
Actually I don't understand why you say you can't link against those functions. Do it in standard way: include header file with such declarations. Use declaration. Linker will do the work for you. Just provide it a path to library with those functions. It will link dynamically to required functions. That's all what you should do. If you don't have such library you need to search for function at runtime manualy with the help of (again) linker at runtime.
You could define a typedef like below:
typedef int (__stdcall *MYFUN)(int, int);
Test case:
int main() {
MYFUN f = MyFunction;
f(2, 3);
}
Alternatively, you could use a std::function object as bellow:
std::function<decltype(MyFunction)> myfun;
Test case:
std::function<decltype(MyFunction)> myfun = MyFunction;
myfun(4, 5);
Live Demo
Got it. decltype(FunctionName)* pointer; will do the job.
You could use decltype or auto, like the following
decltype(&FunctionName) pointer = &FunctionName;
or
auto pointer = &FunctionName;
I avoid manually translating function pointers to types myself in C++11 and C++14 :)
I'm wrapping the Windows API, and I wish to make error checking easy to use, and helpful. Currently, I have a global error object, with a function set to handle a new error. The set function takes four arguments: bool Error::set (const int code, const char * file, const char * const function, const int line); The function uses the file, function, and line arguments to display them in a nicely formatted message.
To ease the setting of errors, there is a macro #define setError() error.set (GetLastError(), __FILE__, __FUNCTION__, __LINE__); This way I'm able to use setError() at any time to respond to an error that an API function has set by adding it after I call that API function.
Unfortunately, this causes the code to look something like this:
SomeAPIFunction();
setError();
AnotherAPIFunction();
setError();
There is also a problem with constructors:
MyClass:MyClass()
: a (SomeAPIFunction), b (AnotherAPIFunction)
{
setError(); //what if both functions set an error?
}
As you can see, by using member initializer syntax, I'm actually limiting myself.
One way to fix this would be to wrap every API function:
int someAPIFunction()
{
int ret = SomeAPIFunction();
setError();
return ret;
}
The function portion of the error message would tell me which function originated the error. Of course, that has to be the worst possible way of dealing with this.
The solution, it seems, is to use variadic templates. The problem is, I have no idea what I'm supposed to be doing to get them working for this. I'd imagine the final code looks something like one of the following:
wrap<int, SomeAPIFunction (5)>();
wrap<int, SomeAPIFunction, 5>();
wrap<int, SomeAPIFunction> (5);
I've read things on beginning variadic templates, but they've all left me clueless of how to set up something like this. Could anyone point me in the right direction?
I found the following on a similar question:
#include <iostream>
template<void f(void)>
struct Wrap {
void operator()() const {
std::cout << "Pre call hook" << std::endl;
f();
}
};
namespace {
void test_func() {
std::cout << "Real function" << std::endl;
}
}
const Wrap<&test_func> wrapped_test_func = {};
int main() {
wrapped_test_func();
return 0;
}
The respondent noted that variadic templates would be a necessity to make this generic enough. It's a start, but I'm lost and grateful of any help on the matter.
I think you'll be able to make it work with this syntax:
wrap(&SomeAPIFunction, arg1, arg2);
The key is to let the compiler use type deduction to determine the template type parameters, since they get pretty messy in a hurry.
The code should look something like:
template<typename TRet, typename... TArgs>
TRet wrap( TRet(WINAPI *api)(TArgs...), TArgs... args )
{
return api(args...);
}
Naturally, you'll want to use a macro to hide the address-of-function operator, use stringizing to store the function name, and store the filename and line number also, passing all of that to the actual variadic function. You'll need variadic macros for that. In fact, could you do all of this just with variadic macros and no templates?