1

I tried running the below code in sololearn code playground, and it is working fine. Could someone please breakdown, why it is working?

I don't know how it's working, since the function add() doesn't accepts any parameter, yet, it receives the add() function as an argument and calculates the sum twice.

#include <stdio.h>

int add(){
    int a,b;
    scanf("%d%d",&a,&b);
    printf("%d",a+b);
    return 0;
}
int main(){
    add(add());
    return 0;
}
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
Sami Khan
  • 31
  • 1
  • 8
  • 3
    what is the question here? Need explanation why this is working or else? – Tom Sep 07 '20 at 10:16
  • I mean how is the function able to executed , I need explanation to that – Sami Khan Sep 07 '20 at 10:18
  • @Sami Khan The code is just incorrect . The compiler should issue a message relative to the incorrect function call.. – Vlad from Moscow Sep 07 '20 at 10:19
  • its taking too much arguments. Sololearn's editor is perhaps outdated. Try this in VScode or VSstudio. – Tom Sep 07 '20 at 10:20
  • @Vlad from Moscow the code works here on sololearn https://code.sololearn.com/cMZdR8U68haX/?ref=app – Sami Khan Sep 07 '20 at 10:20
  • @SamiKhan It is entirely unimportant that the code produces some output. This does not make it correct. – Vlad from Moscow Sep 07 '20 at 10:21
  • @Vlad from Moscow if the code is running without any error, then there must be an explanation to it, right? – Sami Khan Sep 07 '20 at 10:23
  • Apparently it's an undocumented gcc extension (to define a function with empty parameter list). Because documentation is for losers, I guess... – Lundin Sep 07 '20 at 10:28
  • @Lundin It works in clang too, but there I at least get a warning – klutt Sep 07 '20 at 10:29
  • 1
    @SamiKhan There is undefined behavior. – Vlad from Moscow Sep 07 '20 at 10:29
  • 3
    The outer function call `add` doesn't receive *the function* but its return value as argument. In C function calling conventions, the caller is responsible for passing the arguments to the called function and for cleaning up afterwards. The `main` function does the inner call to `add` first and puts the result where the next call would expect the first argument when performing the outer call to `add`. The called function `add` simply ignores any arguments that may be present. – Bodo Sep 07 '20 at 10:41
  • @Bodo The problem here is that the function is defined to take no parameters, so it shouldn't compile cleanly. From what I can tell, a constraint violation of 6.7.6.3/14. – Lundin Sep 07 '20 at 10:49
  • @Lundin I suppose the GCC behaviour argument is that although the function is defined to take no parameters by 6.7.6.3/14, that does not mean it should act as if it has a prototype in scope at the point the function is called, and so 6.5.2.2/2 does not apply to the function call. The behaviour is undefined. – Ian Abbott Sep 07 '20 at 11:00
  • @IanAbbott I guess you are right and it is not a prototype. Hmm, so no constraint violation but "just" undefined behavior? – Lundin Sep 07 '20 at 11:04
  • @Lundin In C2X, if a function declarator has an empty parameter type list and is part of a function definition then it will behave as if it was declared with the parameter type list `void` (see [WG 14 N2478](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2478.pdf) 6.7.6.3/13 and footnote 153), But that is still at draft stage. – Ian Abbott Sep 07 '20 at 11:51

1 Answers1

2

int add() is obsolete style and means accept any parameter (unlike C++ where it means (void)). It's a remain from the old pre-standard "K&R" style where parameters were specified separately. C still allows this form (for now) for function declarators only.

6.11.6 Function declarators
The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.
6.11.7 Function definitions
The use of function definitions with separate parameter identifier and declaration lists (not prototype-format parameter type and identifier declarators) is an obsolescent feature.

When it comes to function definitions with an empty list, the following applies (C11 6.7.6.3/14):

Constraints
/--/
An identifier list declares only the identifiers of the parameters of the function. An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters.

So the code is a constraint violation, it is not valid C. You have a function definition but it apparently gets treated as if it had parameters. gcc specifically appears to be non-compliant here, since I get no diagnostic message even with max warnings and -pedantic.

As for why "it works", see What must a C compiler do when it finds an error? .

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • You are wrong. You would be right if this was a function declaration without its definition. However there is a function declaration with its definition. So the code is in any case incorrect. – Vlad from Moscow Sep 07 '20 at 10:23
  • @VladfromMoscow Hmm yeah indeed, I just checked the text in "future language extensions". – Lundin Sep 07 '20 at 10:25
  • @VladfromMoscow I re-wrote the answer completely. – Lundin Sep 07 '20 at 10:45