0

I want to determine if a function definition actually exist in a class and call that function only if it exists (not just declared). Idea is function declaration will always be present in the class header file but it's implementation (function definition) may or may not be included in the compilation based on the some flags. Catch is that I can not use compiler flags in the source cpp files. Below is what I want to achieve:

class Base {
    public:
    void feature1(int x); // Definition always present
    void feature2(int y); // Definition always present
    void feature3(int z); // Definition may (or may not) be present in another cpp file / library 

};


int main(int argc, char *argv[]) {
    Base a1;

    if (a1.feature3 is available) {  // pseudo code 
        a1.feature3(5); 
    } else {
        printf("feature3 is not available\n");
    }

    return 0;
}

Can someone please help with a possible solution.

  • Duplicate of https://stackoverflow.com/questions/61266803/how-to-use-weak-function-in-c/61269847#61269847 ? – MSalters Apr 17 '20 at 10:58
  • @MSalters I don't think that is what the OP wants though, since that requires the definition to be `#include`'d into the file which checks, so it must be in a header. I _think_ the OP wants to check if a function is defined _across compilation units_ (so different source files). – Object object Apr 17 '20 at 11:07
  • @LonesomeParadise: Did you notice it's the same OP in both questions? – MSalters Apr 17 '20 at 11:28
  • @MSalters I did not :p I still think they are different problems though? – Object object Apr 17 '20 at 11:30

2 Answers2

2

If one method is not defined (but only declare) and you try reference it, linker won't be able to link. Maybe you could try a different approach to the problem (but depends on the requirements that you have), you could try using polymorphism like so:

class Base
{
  public:
     virtual void feature3(){throw NotImplementException()}
} 

class DerivedWithFeature3 : public Base
{
   public:
     void feature3(){/*do something*/}
}

int main(int argc, char *argv[]) {
    Base a1;

   try
   {
       a1.feature3(5);

   }catch(NotImplementException&)
   {
      printf("feature3 is not available\n");
    }

    return 0;
}
SeventhSon84
  • 364
  • 1
  • 4
  • This is in theory a good solution, you use of exceptions to handle logic however bugs me. I think it could be improved by having something like a `virtual bool feature3_implemented()` method which gets overriden and checked for return instead (true for implemented, false for not for example) – Object object Apr 17 '20 at 11:14
  • As I said depends on requirements and depends on the context, if the missing method is something that can be consider an exceptional case, I think is good to use exception, but otherwise you can use another method to check (still based on polymorphism). – SeventhSon84 Apr 17 '20 at 11:16
  • For example if you don't mind to print that the feature is not available, you can remove the throw instruction from the Base class, and let the method do nothing (when the object is an instance of Base class or do something when it is an instance of a derived class that as to do something). – SeventhSon84 Apr 17 '20 at 11:18
  • @LonesomeParadise: In that case, even better IMO `virtual std::unique_ptr feature3();`. – Jarod42 Apr 17 '20 at 12:18
1

The weak symbol should be able to do this for you:

class Base {
    ...
    ...
    void feature3(int z) __attribute__((weak));
}

int main(int argc, char *argv[]) {
    Base a1;

    if (a1.feature3) { 
        a1.feature3(5); 
    } else {
        printf("feature3 is not available\n");
    }
    return 0;
}
james
  • 859
  • 8
  • 22
  • This gives compiler error with g++ on if condition. Though it works fine with gcc. But I need to do it in C++. – Aditya Sharma Apr 17 '20 at 11:12
  • I would not use ` __attribute__((weak))` if I were you. It is not very portable and is not part of the standard. It can also cause weird bugs – Object object Apr 17 '20 at 11:16