Here is a simple C program:
#include <stdio.h>
int main(void)
{
printf("Display something\n");
fflush stdout;
return 0;
}
Compiled with msys2 mingw-w64 gcc version 7.3.0 and option -Wall and everything works fine, just as if the 5th line was fflush(stdout);
.
I tried to reproduce such a call with my own function, but I get the perfectly expected error
src/main.c: In function 'int main(int, char**)':
src/main.c:5:18: error: expected ';' before 'parameter'
custom_function parameter;
^~~~~~~~~
So, what happens with the fflush
function? Can somebody explain me? Do you have the same behavior with other C compilers?
When we call a function with parentheses, the function gets execute and returns the result to the callable. In another case, when we call a function without parentheses, a function reference is sent to the callable rather than executing the function itself.
You can use a default argument in Python if you wish to call your function without passing parameters. The function parameter takes the default value if the parameter is not supplied during the function call.
The call by reference method of passing arguments to a function copies the address of an argument into the formal parameter. Inside the function, the address is used to access the actual argument used in the call. It means the changes made to the parameter affect the passed argument.
Your question:
See Jean-François Fabre's answer. there's an oddity in the wording in the standard (and I make no claim that it's anything more than that).
C99 7.19.1 says:
The header declares three types, several macros, and many functions for performing input and output.
...
The macros are
...
stderr stdin stdout
which are expressions of type "pointer to FILE" that point to the FILE objects associated, respectively, with the standard error, input, and output streams.
As Keith Thompson have said long ago In context, this says they're macros -- but the descriptions of all the other macros use the phrase "which expands to". For stderr, stdin, and stdout, it says they are expressions (which, if they're macros, isn't strictly correct).
If they're allowed to be, say, declared objects rather than macros, then 7.19.1p1 should be changed to allow for these declarations, and the description of stderr, stdin, and stdout shouldn't be part of the page-long run-on sentence.
More plausibly, if they are required to be macros, the phrase "which are expressions" should be changed to "which expand to expressions".
They are not guaranteed to be macros. In your case though, you got lucky the macro expands to an expression with protection brackets. A sheer example of evil macro hiding the actual content.
Let's see preprocessor output (using MinGW, and gcc -E test.c
command line):
fflush
# 5 "test.c" 3
(&(* _imp___iob)[1])
# 5 "test.c"
;
as you see stdout
is a macro which expands to (&(* _imp___iob)[1])
with parentheses.
so the compiler uses those parentheses and the syntax is okay.
But that's only because of macro magic, and the fact that most macros are protected by parentheses to avoid side-effects with other tokens (operator precendence for instance)
You can reproduce that without any includes with this simple code:
#define arg ("hello")
void f(const char *x)
{
}
int main(int argc, char** argv)
{
f arg;
return 0;
}
Of course this is bad practice, confuses IDEs (and humans), so just don't do it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With