8

I have two C functions f1 and f2 that take the same arguments. Based on a condition, I need to invoke one or the other one with the same arguments:

if (condition) {
    result = f1(a, b, c);
} else {
    result = f2(a, b, c);
}

I understand it is possible to use the syntax:

result = condition ? f1(a, b, c) : f2(a, b, c)

Is it be possible to have a DRY syntax that requires to write arguments a single time?

enrico.bacis
  • 30,497
  • 10
  • 86
  • 115
  • in you first code paragraph, in 'else' clause, it should be `f2` – Pierre May 04 '16 at 15:27
  • what do you mean by calling same function `f1` if `condition` is both true and false? If this is a typo please correct it. – user3078414 May 04 '16 at 15:27
  • yes of course it should be f2, thanks – enrico.bacis May 04 '16 at 15:32
  • I have to wonder if you tried the code that you put into your question before asking. It actually works as written, obviating the complicated answer that you posted. – David Hoelzer May 04 '16 at 15:39
  • @DavidHoelzer actually I did but using a much more complicated function, now I'll try again – enrico.bacis May 04 '16 at 15:40
  • Why didn't you try it? Wouldn't that be quicker than asking here? It works, as long as `f1` and `f2` have been declared before you try to use them (but you wouldn't be trying to compile code that doesn't declare or define functions before you use them, would you — that is so much a thing of the last millennium!). – Jonathan Leffler May 04 '16 at 15:41
  • Actually, there is no `? ...:` in Python, thus it is not clear what you mean with "pythonic syntax". And the semantics are very different in both languages. – too honest for this site May 04 '16 at 15:54
  • Thank you all for your suggestions, I improved the question leaving only the details that make the question useful. – enrico.bacis May 04 '16 at 20:02

2 Answers2

9

Yes, it works fine just like you suggested.

The function call operator () just needs a left-hand-side that evaluates to a function pointer, which names of functions do.

There's no need to derefence function pointers when calling, the () operator does that.

This sample program demonstrates:

#include <stdio.h>

static int foo(int x) {
    return x + 1;
}

static int bar(int x) {
    return x - 1;
}

int main(void) {
    for (int i = 0; i < 10; ++i)
        printf("%d -> %d\n", i, (i & 1 ? foo : bar)(i));
    return 0;
}

It prints:

0 -> -1
1 -> 2
2 -> 1
3 -> 4
4 -> 3
5 -> 6
6 -> 5
7 -> 8
8 -> 7
9 -> 10

There is nothing strange here.

And since C predates Python by a fair bit, perhaps it's Python's semantics that are C-ish here. Or just plain sane, of course. :)

unwind
  • 391,730
  • 64
  • 469
  • 606
  • The structure is similar, but neither the syntax (Python does not have `? .. :`, but `if .. else` operators) nor the mechanisms are the same. Unlike C++ for instance, Python is full-grown OOP and functions are first-class objects, too - as are classes. – too honest for this site May 04 '16 at 15:53
2

It is possible to use a function pointer like this:

int (*f)(int, int, int, ...);
f = condition ? f1 : f2;
result = (*f)(a, b, c, ...);
enrico.bacis
  • 30,497
  • 10
  • 86
  • 115
  • 1
    @Jack, you should reread the help section about asking questions. We are encouraged to answer our own question if we can. This is not just about help, this is about increasing the knowledge base at SO. – StoryTeller - Unslander Monica May 04 '16 at 15:20
  • 2
    @enrico.bacis but as far as I know, your "pythonic" syntax should also work fine, provided the functions have the same types/signatures! See also http://stackoverflow.com/questions/75538/hidden-features-of-c#comment4498219_302563 – CherryDT May 04 '16 at 15:21
  • 1
    Why did you introduce a temporary variable? `result = (condition ? f1 : f2)(a, b, c, …)` would work as well. – The Paramagnetic Croissant May 04 '16 at 15:28
  • @Jack: http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/ The idea is: "I know this way, do you know a better one?" – enrico.bacis May 04 '16 at 15:33
  • I can't up vote this since it unnecessarily complicates the issue and defeats the request for a Pythonic approach. @unwind's answer is much superior. – David Hoelzer May 04 '16 at 15:38
  • I know you can answer your own question, I've did it. I mean the way he wrote it 'you could'... – Jack May 04 '16 at 15:51
  • @Jack You are right, fixed it. It was actually creepy, thanks! ;) – enrico.bacis May 04 '16 at 20:01