c++ function call with square parenthesis

c square brackets
what is function call in c
how to call a void function in c
function without argument and with return value in c
c++ square brackets operator
functions in c
array in c
c initialize function
int func(int n)
{return n;}

int main()
{ cout << func[4] ;
cout << func[4,3,5] ;}

what do these actually mean? I guess it is about accessing func+4 and func is allocated space on calling func[4]. But, func[4,3,5] is just absurd.

The reason this code compiles and func[4] is not a syntax error is:

1.Function types can implicitly convert to pointers of the same type. So, if we have code like this:

int f(int);

using func_t = int(*)(int);

void g(func_t);

we can write

g(f)

and aren't forced to write g(&f). The &, taking us from type int(int) to int(*)(int) happens implicitly.

2.In C (and necessarily in C++ for compatibility) pointers are connected to arrays, and when p is a pointer p[x] is the same as *(p + x). So func[4] is the same as *(func + 4).

3.*(p+x) has the type of a function int(int), but again can implicitly decay to a pointer type whenever necessary. So *(func + 4) can implicitly just be (func + 4).

4.Pointers of any type are streamable to std::cout.


Note, that just because it isn't a syntax error doesn't mean it is valid. Of course it is undefined behavior, and as the compiler warning emitted by gcc and clang indicates, pointer arithmetic with a function pointer is generally wrong, because you cannot make an array of functions. The implementation places functions however it likes. (You can make an array of function pointers but that is something else entirely.)


Edit: I should correct myself -- this answer is not entirely correct. func[4] is not valid, because the pointer is not a pointer to an object type. @holyblackcat answer is correct, see his answer for reference in the standard.

This code should be ill-formed, and gcc only compiles it without an error because they are using a nonstandard extension by default. Clang and msvc correctly reject this code.

IOS 7 Programming Fundamentals: Objective-C, Xcode, and Cocoa Basics, Parentheses after the function name in the function call are how C knows this is a and the call to that function into a single program: int square(int i) { return i * i; }​  A function is a group of statements that together perform a task. Every C program has at least one function, which is main (), and all the most trivial programs can define additional functions. You can divide up your code into separate functions. How you divide up your code among different functions is up to you, but logically the division is such that each function performs a specific task.

I'm surprised no answer mentions it, but:

The code in the question is simply not valid C++.

It's rejected by Clang and MSVC with no flags. GCC rejects it with -pedantic-errors.

a[b] (in absence of operator overloading) is defined as *(a + b), and the builtin operator + requires the pointer operand to be a pointer to an object type (which functions pointers are not).

[expr.add]/1

...either both operands shall have arithmetic or unscoped enumeration type, or one operand shall be a pointer to a completely-defined object type and the other shall have integral or unscoped enumeration type.

(Emphasis mine.)


GCC compiles the code because an extension allowing arithmetic on function pointer is enabled by default.

Due to function-to-pointer decay, func[4] is treated as &(&func)[4], which effectively means &func + 4, which (as the link explains) simply adds 4 to the numerical value of the pointer. Calling resulting pointer will most likely cause a crash or unpredicatble results.

std::cout doesn't have an overload of << suitable for printing function pointers, and the best suitable overload the compiler is able to find is the one for printing bools. The pointer gets converted to bool, and since it's non-null, it becomes true, which is then printed as 1.

Lastly, func[4,3,5] has the same effect as func[5], since in this context , is treated as an operator, and x , y is equal to y.

Programming iOS 4: Fundamentals of iPhone, iPad, and iPod touch , Parentheses after the function name in the function call are how C knows this is a definition and the call to that function into a single program: int square(int i)  2.In C (and necessarily in C++ for compatibility) pointers are connected to arrays, and when p is a pointer p[x] is the same as *(p + x). So func[4] is the same as *(func + 4) . 3. *(p+x) has the type of a function int(int) , but again can implicitly decay to a pointer type whenever necessary.

Since it has not been mentioned yet: func[3, 4, 5] is identical to func[5] - the commas in there are the builtin comma operator which evaluates the left hand side expression, discards it and then evaluates the right hand side expression. There is no function call happening here and the commas in the code are not delimiting function parameters.

Programming IOS 6, Parentheses after the function name in the function call are how C knows this is a and the call to that function into a single program: int square(int i) { return i * i; }​  Prev Next pow( ) function in C is used to find the power of the given number. ”math.h” header file supports pow( ) function in C language. Syntax for pow( ) function in C is given below. double pow (double base, double exponent); Example program for pow() function in C: COMPILE & RUN Output: 2 power 4 = 16.000000 5 power 3 = 125.000000 Other inbuilt arithmetic functions in C: “math.h

Yes,It is about accessing the func+4 which is not already defined leading to a garbage value.So the compiler will indicate you with the following warning message.

hereProgram: In function 'int main()':
Program:7: warning: pointer to a function used in arithmetic

C for BASIC Programmers, C treats array subscripts (specified with square brackets) and function calls (​specified with parentheses) as operators. Like other operators, the subscript and​  The only addition being that now the function call is also an operand of an addition operation. Again, the result is the same as if the function call was replaced by its result: 6. Note, that thanks to the commutative property of additions, the above can also be written as:

Obscure C++ Features, What square brackets really mean &Test::num; void (Test::*ptr_func)() = &Test::​func; int main() { Test t; Test *pt = new Test; // Call the stored member function (t. The parenthesis operator (operator()) is a particularly interesting operator in that it allows you to vary both the type AND number of parameters it takes. There are two things to keep in mind: first, the parenthesis operator must be implemented as a member function. Second, in non-object-oriented C++, the operator is used to call functions.

Operators in C, The data items that operators act upon are called operands. an expression in square brackets [ ] is a subscripted designation of the array element . Arguments passed to non prototyped C functions undergo conversions:  This is a specific type of cast called a C-Style cast. What it does in this case is transform the return type of the function to an int. In addition to this, C++ has several variants.

C Programming Course Notes - Functions, Calling a Function. A function is called by using the function name, followed by a set of parentheses containing the data to be passed to the function. With the function pointer what I was hoping to achieve was to avoid the if/else if test on every frame and just update the function pointer which will allow me to call the right function. I hope this makes sense. I can give a code example that more closely aligns with what I am trying to achieve with the function pointers. Thank you for your time.

Comments
  • If you are using gcc or clang, I would recommend turning on -Wall which emits a warning here
  • actually I wanted to know more about the concept than handling the issue. thanks
  • I think it's a bug that the compilers don't give any message by default. [expr.sub] says "The type T shall be a completely defined object type."
  • I don't think it means anything useful, and there is not much concept to know more about. Function name, func here, is a pointer (to the function). Using array [] after function pointer makes no sense, you can't have array of functions. I think (but I am not sure), that function "value" is always interpreted as a pointer, so unlike normal arrays, func[4] is actually also pointer to function (its type is, I mean). But it is not a valid pointer, so actually even creating it is technically speaking undefined behavior.
  • You may or may not be getting a warning about this. If you aren't, yuck. If you are, never ignore warnings. Warnings are the compiler telling you that It can convert the code into a program, but the program probably doesn't do what you want. Understand the warning and either fix it or confirm that it is the behaviour you want. If you want this behaviour, try to rewrite the code so that the warning is not emitted so that you don't have noise in the build output.
  • No, it's not UB. It's simply invalid C++. GCC with -pedantic-errors emits error: pointer to a function used in arithmetic [-Wpointer-arith].
  • I think it is UB because when the compiler sees *(f+ 4) it is normally a promise to the compiler that the address f+4 contains a valid value of type decltype(*(f+4)). Since that isn't true you get UB no diagnostic required. (These warnings are just the compiler being nice to you but the standard doesn't require that a conforming implementation emits a warning here.) Its UB even if you don't ultimately "use" the value and instead immediately take its address again. This doesn't count as a discarded value expression. * ing a pointer is like a blood oath :)
  • For instance if you add e.g. null check after std::cout << f[4] I expect that a conforming compiler can drop null checks at f+4 because you have implicitly starred this pointer, c.f. blog.llvm.org/2011/05/…
  • Nope, it's invalid C++. operator+ requires the pointer operand to be a pointer to an object type (which functions pointers are not).
  • Thanks! So does this mean the program is ill formed and conforming compilers must reject it, so it is a defect that gcc and clang merely give a warning? I thought the possible status of a program is like, ill formed, well formed but with undefined behavior, implementation defined, and having well defined behavior. I remember that "ill formed no diagnostic required" is a thing, is that what you think is happening here?