1

EDIT: Apologies for the previous mess.

I came to a code example which goes like

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

    int main(int argc, char *argv[])
    {
        int num = (round)(3.14*2 / 1.618);
        printf("test %d test", num);

        int num2 = (round)(3.0 / 2.0);
        printf("test %d test", num2);
    }

What does this (round) do? Is this a function invocation of the round function from math.h? Does this mean I am effectively invoking a function at the location of (round) pointer? Does this mean (myFun+1)(myVar) could work in some case?

ditoslav
  • 4,563
  • 10
  • 47
  • 79
  • Typically that's the syntax for a typecast, but no way to tell without more of the surrounding code. – anonmess Oct 22 '19 at 14:30
  • 3
    Somewhere, you should be able to find `typedef .... round;` Show the details of that code. It is possible that `round` is a function-pointer defined somewhere. – abelenky Oct 22 '19 at 14:31
  • 6
    It might be forcing a function call in preference to expanding a macro. – Ian Abbott Oct 22 '19 at 14:32
  • It's either a function call, or a type-cast. But without more context it's impossible to say. – Some programmer dude Oct 22 '19 at 14:32
  • 1
    I didn't know this, but `(printf)("abc\n");` compiles and runs with MSVC. – Weather Vane Oct 22 '19 at 14:33
  • @WeatherVane Well the function "name" is just like any other expression (otherwise function pointers would not work), and thus could be surrounded by parentheses. – Some programmer dude Oct 22 '19 at 14:34
  • Surprising for me too, however, although there is indeed no reason against it... – Ctx Oct 22 '19 at 14:34
  • 1
    ...which means that `(round)` is not necessarily a typecast. More code is needed. – Weather Vane Oct 22 '19 at 14:34
  • 1
    Function pointers do not support addition or subtraction (unlike pointers to objects), so `(myFun+1)(myVar)` wouldn't work. – Ian Abbott Oct 22 '19 at 14:35
  • 2
    @WeatherVane `(*printf)("abc\n");` should also compile and run correctly. – Ian Abbott Oct 22 '19 at 14:42
  • 3
    @IanAbbott And thus even `(*************printf)("abc\n");` – Ctx Oct 22 '19 at 14:44
  • @IanAbbott indeed it does / they do (at Ctx). – Weather Vane Oct 22 '19 at 14:44
  • Please show also the types of `ky`, `dcty`, `ktab1` etc. But probably it's some legacy code. Best is you show a [mcve]. Otherwise we can only guess. – Jabberwocky Oct 22 '19 at 15:00
  • Related: https://stackoverflow.com/questions/13600790/what-do-the-parentheses-around-a-function-name-mean I don't feel it's a full duplicate as it deals with function definition, while this question deals with calling functions. – Andrew Henle Oct 22 '19 at 15:07
  • I've cleaned up the code example with extracted code to a new isolated c file – ditoslav Oct 22 '19 at 15:09
  • Incidentally, if you want to know whether the `(x)` in `(x)(y)` is a cast or a function call without traipsing through all the source files and headers to find a definition, just add more parentheses: `((x))(y)` will compile if `x` is a function and not if `x` is a type. – Eric Postpischil Oct 22 '19 at 15:52
  • Possible duplicate of [What do the parentheses around a function name mean?](https://stackoverflow.com/questions/13600790/what-do-the-parentheses-around-a-function-name-mean) – ShadowRanger Oct 22 '19 at 18:53
  • 1
    Note that [my suggested duplicate](https://stackoverflow.com/q/13600790/364696) isn't asking the exact same thing, but the answers cover this case too, and [other](https://stackoverflow.com/q/27644805/364696) [questions](https://stackoverflow.com/q/49729878/364696) about this have duped to it. – ShadowRanger Oct 22 '19 at 18:55

1 Answers1

3

With <math.h> included, round is a standard C rounds its argument to the nearest integer, rounding halfway cases away from zero, and returning a double.

Technically, round is a function designator: It denotes the function. (round) is merely the designator in parentheses. Like other parenthesized expressions, its type and value are the same as the expression inside it. So, functionally, (round) is the same as round, and (round)(3.14*2 / 1.618) is the same round(3.14*2 / 1.618)

One difference is that <math.h> may implement round as a function-like macro. In this case, in round(x), the macro is expanded, and the resulting expression may be something other than a function call, or it could call a function with a different name. (The C standard requires the result to be the same as if the round function had been called.) In (round)(x), the macro name round is not immediately followed by a left parentheses, so the expansion of the function-like macro does not occur. Thus (round)(x) calls the actual function even if a function-like macro is defined.

This behavior regarding putting function names in parentheses to suppress macro expansion is a deliberate feature of the C library (C 2018 7.1.4 1: “… Any macro definition of a function can be suppressed locally by enclosing the name of the function in parentheses,…”). However, there is no apparent reason to use it in this code.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312