Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to determine (at runtime) if a function has been implemented?

One of Objective C's primary features is simple introspection. A typical use of this functionality is the ability to check some method (function), to make sure it indeed exists, before calling it.

Whereas the following code will throw an error at runtime (although it compiles just fine (Apple LLVM version 7.0.2 (clang-700.1.81)))...

@import         Foundation;
@interface      Maybe : NSObject + (void) maybeNot; @end
@implementation Maybe                               @end

int main (){ [Maybe maybeNot]; }

By adding one simple condition before the call...

if ([Maybe respondsToSelector:@selector(maybeNot)])

We can wait till runtime to decide whether or not to call the method.

Is there any way to do this with "standard" C (c11) or C++ (std=c14)?

i.e....

extern void callMeIfYouDare();

int main() { /* if (...) */ callMeIfYouDare(); }

I guess I should also mention that I am testing/using this is in a Darwin runtime environment.

like image 826
Alex Gray Avatar asked Dec 05 '25 10:12

Alex Gray


2 Answers

On GNU gcc / Mingw32 / Cygwin you can use Weak symbol:

#include <stdio.h>

extern void __attribute__((weak)) callMeIfYouDare();

void (*callMePtr)() = &callMeIfYouDare;

int main() {
        if (callMePtr) {
                printf("Calling...\n");
                callMePtr();
        } else {
                printf("callMeIfYouDare() unresolved\n");
        }
}

Compile and run:

$ g++ test_undef.cpp -o test_undef.exe

$ ./test_undef.exe
callMeIfYouDare() unresolved

If you link it with library that defines callMeIfYouDare though it will call it. Note that going via the pointer is necessary in Mingw32/Cygwin at least. Placing a direct call callMeIfYouDare() will result in a truncated relocation by default which unless you want to play with linker scripts is unavoidable.

Using Visual Studio, you might be able to get __declspec(selectany) to do the same trick: GCC style weak linking in Visual Studio?

Update #1: For XCode you can use __attribute__((weak_import)) instead according to: Frameworks and Weak Linking

Update #2: For XCode based on "Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)" I managed to resolve the issue by compiling with the following command:

g++ test_undef.cpp -undefined dynamic_lookup -o test_undef

and leaving __attribute__((weak)) as it is for the other platforms.

like image 196
ALGOholic Avatar answered Dec 08 '25 00:12

ALGOholic


If you can see a function of an object (not pointer) is called in a source code and the code is compiled successfully - then the function does exist and no checking needed.

If a function being called via a pointer then you assume your pointer is of type of the class that has that function. To check whether it's so or not you use casting:

auto* p = dynamic_cast<YourClass*>(somepointer);
if (p != nullptr)
  p->execute();
like image 27
Andrey Lyubimov Avatar answered Dec 07 '25 22:12

Andrey Lyubimov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!