klutt
klutt

Reputation: 31306

Are parentheses always considered a function call?

I was looking at this page: https://en.cppreference.com/w/c/language/operator_precedence

What caught my attention was that the only description of the parenthesis operator was function call. Does this mean that the expression x = a * (b+c)-(d*e) has two function calls?

I searched in C grammar and C standard but I was unable to find anything that either supports or contradicts this.

Upvotes: 5

Views: 843

Answers (3)

Joshua
Joshua

Reputation: 43268

No. identifier( calls identifier as a function. If there's no identifier or complete expression immediately left of the parentheses there is no call.

When I was first learning c I had the opposite problem. I couldn't figure out why clrscr; didn't clear the screen. (It's an expression that evaluates to a pointer to clrscr but does nothing with it).

In fact you can have expressions of type pointer to function, and those expressions can be called with (), and the grammar is completely unambiguous between the two. So clrscr(); is a function call, and so is (clrscr)(). On reaching function pointers, we can do resolve_function()() as well. The operation is always ( immediately after an expression, not after an operator. If it's after an operatior, it must be grouping parenthesis.

Upvotes: 2

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

A function call is a postfix expression.

Here in these expressuins

x = a * (b+c)-(d*e);

subexpressioins (b+c) and (d*e) are primary expressions. You may enclose any expression in parentheses and you'll get a primary expression.

For example you could even rewrite the expression statement the following way

( x = ( ( ( a ) * (b+c) )-(d*e) ) );

In this expression statement there are the following primary expressions

( a )
(b+c)
(d*e)
( ( a ) * (b+c) )
( ( ( a ) * (b+c) )-(d*e) )
( x = ( ( ( a ) * (b+c) )-(d*e) ) )

Here are some examples of postfix expressions

( *p )() // a function call

a[n] // using the subscript operator

x++; // using the postfix increment operator

The definition of a function call is

postfix-expression:
    primary-expression
    postfix-expression ( argument-expression-listopt )

From the C Standard (6.5.2.2 Function calls)

1 The expression that denotes the called function92) shall have type pointer to function returning void or returning a complete object type other than an array type.

Here are some examples of weird function calls.:)

#include <stdio.h>

void f( void )
{
    printf( "Hello " );
}

void g( void )
{
    puts( "Broman" );
}    

int main( void )
{
    void ( *funcs[] )( void ) = { f, g };

    void ( **p_func )( void ) = funcs;

    ( *p_func++ )();
    p_func[0]();
}

The program output is

Hello Broman

Take into account that in these calls

    ( *p_func++ )();
    p_func[0]();

expression ( *p_func++ ) is a primary expression and expression p_func[0] is a postfix expression (See the partial definition of the postfix expression above)

Upvotes: 4

dbush
dbush

Reputation: 223739

Parenthesis can be used as a function call operator, but that's not the only thing they're used for. They are also used for expression grouping as in your example.

What you're looking for is in section 6.5.1 of the C standard which discusses Primary Expressions:

Syntax

1

primary-expression:
  identifier
  constant
  string-literal
  ( expression )
  generic-selection

...

5 A parenthesized expression is a primary expression. Its type and value are identical to those of the unparenthesized expression. It is an lvalue, a function designator, or a void expression if the unparenthesized expression is, respectively, an lvalue, a function designator, or a void expression.

As stated above, parenthesis can be used to group expressions.

The use as a function call operator is detailed in section 6.5.2 on Postfix Expressions:

postfix-expression:
  ...
  postfix-expression(argument-expression-list opt)
  ...

So in your expression:

x = a * (b+c)-(d*e)

The use of parenthesis here matches a Primary Expression but not a Postfix Expression.

Also, besides expression grouping, parenthesis are used in other parts of the language grammar. Section 6.8.4 regarding Selection Statements uses parenthesis in the grammar of if and switch statements:

  • if (expression) statement
  • if (expression) statement else statement
  • switch (expression) statement

And section 6.8.5 regarding Iteration Statements also use parenthesis in the grammar of while and for statements.

  • while (expression) statement
  • do statement while (expression);
  • for (expressionopt; expressionopt; expressionopt) statement
  • for (declaration expressionopt; expressionopt ) statement

Upvotes: 6

Related Questions