3

I stumbled over a weird piece of code that I thought would not work the way it is intended, but it did. Example:

#include  <stdio.h>
#include <stdlib.h>

int main(void)
{
    printf("%d\n", abs(-1)); // output: 1
    printf("%d\n", (abs)(-1)); // output: 1
    return 0;
}

Apparently putting parenthesis around the function name in a function call has no effect on the program. It just makes it look like a cast.

I am kinda interested if this is defined somehow. But I figure that it just not forbidden and that's why it works.

What I am really curious about is, is there a case where this kind of notation might yield an advantage in any kind? (structure of the code, readability, anything this might be useful for)

Or is it just a "weird" way to write code?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Kami Kaze
  • 2,069
  • 15
  • 27
  • 2
    Can it be useful? Sometimes https://stackoverflow.com/questions/13416418/define-nominmax-using-stdmin-max/13420838#13420838 – StoryTeller - Unslander Monica Apr 09 '18 at 09:42
  • 2
    Once upon a time, I had the really bad idea to replace some common function with mine by using a #define, like #define malloc my_malloc. This way, all call to "malloc" will be replaced by mine. The only way to call the original function was to surparenthese it, like "(malloc)(...)". From this time, every-time I see something like that, I become really suspicious. Fortunatly, it's really really really rare. – Tom's Apr 09 '18 at 09:45
  • @Tom's now I am even more intrigued that you could maneuver around the define like this. You could make an answer out of this. – Kami Kaze Apr 09 '18 at 09:47
  • https://stackoverflow.com/questions/1951885/macro-and-function-with-same-name – Antti Haapala -- Слава Україні Apr 09 '18 at 09:50
  • The function name is a simple expression, but here can be any expression which has type of function. – freestyle Apr 09 '18 at 09:51
  • @KamiKaze : unfortunatly, I do not know why preprocessor work like that, I only he work this way. So an answer won't be good, unless I dig some manual or specification reference. – Tom's Apr 09 '18 at 09:55
  • If you want to ask *"what makes the preprocessor exhibit this behavior"*, then you can always post another question. I don't believe there's a duplicate for that one. – StoryTeller - Unslander Monica Apr 09 '18 at 09:58
  • @AnttiHaapala not exactly the same (one is definition one is call), but interesstingly I haven't found this and the answer is the same. So I take the dupe. – Kami Kaze Apr 09 '18 at 09:58
  • 1
    @KamiKaze it is the same in essence that: avoiding macro expansion in-place. – Antti Haapala -- Слава Україні Apr 09 '18 at 10:28
  • 1
    I cannot seem to find the qa that actually spells this out, but: ["Any function declared in a header may be additionally implemented as a function-like macro defined in the header ... Any macro definition of a function can be suppressed locally by enclosing the name of the function in parentheses, because the name is then not followed by the left parenthesis that indicates expansion of a macro function name."](http://port70.net/~nsz/c/c11/n1570.html#7.1.4p1) – Antti Haapala -- Слава Україні Apr 09 '18 at 10:32
  • 1
    Ok, now I found a proper duplicate – Antti Haapala -- Слава Україні Apr 09 '18 at 10:34

1 Answers1

4

Try

int foo(int a, int b) { return a+b; }
#define foo(a,b) ((a)+(b)+1)
#include <stdio.h>

int main() {
    printf("%d %d\n",
        foo(3, 5),  // Use macro if defined
        (foo)(3, 5)  // Always call function even if there's a macro
    );
    return 0;
}

Output:

9 8

See the difference?

iBug
  • 35,554
  • 7
  • 89
  • 134