1

I have a testing file with tests defined as

static int test1(){
    /*some tests here*/
    return 0;
}
static int test2(){
    /*some tests here*/
    return 0;
}
/*...etc*/`

and I was wondering if there's a way to call all of the tests in a loop, instead of writing the call for each one. (There are some functions I need to call before and after each test, and with >20 tests, this might get really annoying. I've also just been curious about doing things like this for a while.)

I was thinking something similar to:

int main(){
    int (*test)() = NULL;
    for(i = 1; i <= numtests; i++){
      /*stuff before test*/
      (*test)();
      /*stuff after test*/
    }
    return 0;
}

but I'm not sure how to proceed with using the value of "i" to set the test pointer.

Benesh
  • 3,398
  • 1
  • 18
  • 38
  • What platform are you on? Technically speaking, on a *NIX platform, you should be able to use `dlsym` and friends to dynamically invoke the function by name, though I wouldn't really recommend it. – Richard J. Ross III Mar 27 '14 at 23:40
  • I'm ssh'd into my school's linux servers. I have no idea what dlsym does, and I don't want to confuse myself right now, but I'll look it up later. A working (and fun-looking) solution was posted below, but thanks for responding :) – SaintlyWolf Mar 28 '14 at 18:39

3 Answers3

1

On linux

put the functions in a separate shared library (.so). Then use dlopen to open it and dlsym to get a function pointer by its name

On windows

put the functions in a separate dll (basically the same thing). Then use LoadLibrary to open it and GetProcAddress to get a pointer to the function

A lot more typing that you wanted to do , but it will let you do what you want

pm100
  • 48,078
  • 23
  • 82
  • 145
1

You can use a self inclusion trick to get a list of function pointers:

#ifndef LIST_TESTS
#define TEST(name, ...) static int name() __VA_ARGS__

/* all includes go here */
#endif // ifndef LIST_TESTS

TEST(test1, {
  /* some tests here */
  return 0;
})

TEST(test2, {
  /* some tests here */
  return 0;
})

#undef TEST

#ifndef LIST_TESTS
int main(void) {
  int (*tests[])() = {
    #define LIST_TESTS
    #define TEST(name, ...) name,
    #include __FILE__
  };
  int num_tests = sizeof(tests) / sizeof(tests[0]);
  int i;

  for (i = 0; i < num_tests; ++i) {
    /* stuff before test */
    (tests[i])();
    /* stuff after test */
  }

  return 0;
}
#endif // ifndef LIST_TESTS
reima
  • 2,076
  • 15
  • 22
  • Thanks, that's a wonderful solution! Can you explain how the "__VA_ARGS__" part works? Does it just grab whatever is in the parameter slot for "..."? – SaintlyWolf Mar 28 '14 at 01:52
  • @SaintlyWolf `__VA_ARGS__` gets replaced by whatever parameters were supplied to the macro at the `...` position. Without that construct, you would have trouble using commas in the test body. `LIST_TESTS` is defined in `main`. – reima Mar 28 '14 at 02:02
  • I really appreciate your help with this. It's something I've wondered for a long while. Sadly, the compiler options my professor requires for this class prevent variadic macros. I'll be sure to remember this for after I'm done with this class, though! – SaintlyWolf Mar 28 '14 at 02:43
0

What you can do is define an array of function pointers with all your functions and then loop in all elements of the array.

int (*array[])(void) = {test1, test2, test3};
ouah
  • 142,963
  • 15
  • 272
  • 331
  • Thanks for the answer. I'd thought of that already, but was hoping for a method that doesn't involve typing the function names at all. Not saying I mind typing them, I just want to be able to do it, if the language allows. – SaintlyWolf Mar 27 '14 at 23:34
  • 1
    @SaintlyWolf I cannot think of any better solution. – ouah Mar 27 '14 at 23:36
  • @SaintlyWolf You have to reference the actual function at some point. – this Mar 27 '14 at 23:47