我可以重新定义一个函数或检查它是否存在?

我有一个关于(重新)定义函数的问题。 我的目标是有一个脚本,我可以选择定义一个函数。 像这样:

void func(){} int main(){ if (func)func(); } 

没有这个function,只需:

 int main(){ if (func)func(); } 

有人有想法吗?

您可以使用其弱函数属性扩展在GCC中执行此操作:

 void func() __attribute__((weak)); // weak declaration must always be present int main() { if (func) func(); // ... } // optional definition: void func() { ... } 

即使在另一个.c文件或库中定义了func()这也可以工作。

我想是这样的。 没有多少使用函数指针,所以我的语法可能略有错误。

  void func() { #define FUNC_PRESENT // code } void (*funcptr)(); #ifdef FUNC_PRESENT funcptr = func; #else funcptr = NULL; #endif int main() { if (funcptr) funcptr(); } 

使用函数指针,根据运行时条件动态设置它们,并检查空指针或将它们包装在执行该检查的方法中。

只有CI的选项才能想到。

在C ++中,您可以组合模板和DLL以在运行时动态定义。

实际上,您可以“选择是否定义函数”的唯一方法是使用C预处理程序指令。 例如:

 #ifdef some_name void func() { do_whatever(); } #else //the else part is optional #endif 

要设置这些“变量”,请使用#define some_name

问题是,所有这些都需要在编译时完成(在此之前,实际上),所以无法使用if示例中的if语句完成。 如果你想要一个if语句来控制你的程序流,只需使用它,而不必费心去尝试重命名函数或使用函数指针等。

介绍

我猜你正试图这样做:

  • 两个模块, aobo
  • bo包含void foo()的定义
  • 只有bo也链接到最终的可执行文件时, ao 才会调用void foo()

这对于“插件”系统可能很有用。


变化1

您可以使用函数指针进行模拟。 我不知道足够的C用适当的C代码写这个,但伪代码看起来像这样:

 extern collectionOfFuncPtrs_t list; int addFuncPtr(); 

AC

 #include "ah" collectionOfFuncPtrs_t list; int addFuncPtr(FuncPtr p) { - add func ptr to list - return 0 } int main() { - loop through list of function pointers - call functions through them } 

公元前

 #include "ah" void bar() { /* ... */ } static int dummy = addFuncPtr(&bar); 

CC

 #include "ah" void ayb() { /* ... */ } static int dummy = addFuncPtr(&ayb); 

结论

现在,您可以根据需要链接bo和/或co ,而int main()只会调用bar()和/或ayb()如果存在)。


变化2

尝试使用此主题的变体,如果它看起来可能对您有用。 特别是,如果您只有特定数量的条件定义函数,则可以使用一堆单独的函数指针而不是某些列表:

 extern fptr_t bar_ptr, ayb_ptr; 

AC

 #include "ah" int main() { if (bar_ptr) bar_ptr(); if (ayb_ptr) ayb_ptr(); } 

公元前

 #include "ah" void bar() { /* ... */ } fptr_t bar_ptr = &bar; 

b_dummy.c

 #include "ah" fptr_t bar_ptr = 0; 

CC

 #include "ah" void ayb() { /* ... */ } fptr_t ayb_ptr = &ayb; 

c_dummy.c

 #include "ah" fptr_t ayb_ptr = 0; 

结论

现在要么链接bob_dummy.o ; 并链接coc_dummy.o

无论如何,我希望你能得到一般的想法……!


Bootnote

在C ++中,这容易,您可以使用std::map和构造函数轻松编写模块注册系统。

在C? 只能使用其他答案中所述的预处理器。

C不是像Python这样的动态语言。

在C中做我认为你要问的正确方法是使用函数指针 。 您可以获取函数的地址,将其分配给变量,将其测试为nil等。但是,普通的旧C不是一种非常动态的语言; 你可能最好使用不同的语言。

如果你不介意编译器特定的扩展,你可以使用__if_exists

 #include  using namespace std; // uncomment the following, and it'll still work void maybeFunc(){ cout << "running maybe" << endl; } int main(){ cout << "hi!" << endl; __if_exists(maybeFunc) cout << "maybe exists!" << endl; maybeFunc(); } } 

默认情况下,这在msvc中有效,如果使用-fms-extensions标志,则在clang中-fms-extensions