This question already has answers here:
Why would you declare variables in the middle of defining a function?
(2 answers)
Closed 7 years ago.
What does it mean if something like the two lines after the main function declaration appears in C code?
int main(argc,argv)
int argc;
char *argv[];
{
// main function body
}
I've never seen anything like this before. The code works just fine, but I'm curious to know what this means. Thanks!
This is the original (read: ancient) style of declaring argument parameters in K&R C. In ANSI C standards, the form you're likely familiar with has been the standard.
See also: What are the major differences between ANSI C and K&R C?
It is just one other way of declaring the datatype of arguments of that particular function.
That's "K&R" C. It's way out of date.
Don't use it, even if your compiler supports it. Arguments passed to a function defined in that manner will have undergone argument promotion so that every argument has the same size (via the same mechanism that varargs are promoted in up-to-date C code).
Such code also does not support function declarations/prototypes. And never try to "improve" such code by creating function prototypes - you'll break the argument promotion that the function is expecting.
Related
This question already has answers here:
Function without return type specified in C
(3 answers)
Closed 2 years ago.
I'm very new to C programming and am confused as to why functions like int main(){} include "int"? As far as I can tell, it functions fine without the data type, and leaving out the data type would make it easier to read and would be similar to languages I'm already familiar with like JS. What am I missing?
When you omit the return type for a function in C, it is defaulted to int and
any calls to this function that expect anything that cannot be typecast to int will get compiler warning/error. Its good programming practise to include function return type since not all functions always return int.
would be similar to languages I'm already familiar with like JS
No it is not similar. In languages like JS, they can return any data type and the rest of the code knows what to expect depending on the function and arguments. However in C, omitting return type does not mean it can return any datatype. It means it can return only int. So in your case, it would be even more confusing.
This question already has answers here:
Alternative (K&R) C syntax for function declaration versus prototypes
(5 answers)
Closed 3 years ago.
At C lang FAQ I found the following code:
void f(ipp)
int **ipp;
{
static int dummy = 5;
*ipp = &dummy;
}
I tested compiling it with -Wall -std=c11 -pedantic flags, and it compiled with no warnings or errors. How is that possible - a variable declared between the function name and its block?
Edit:
A few hours after posting, and after a number of answers, I find the question is closed as a duplicate. I don't agree with the decision to close. In fact, the duplicate Q&A and the answers given here so far, although broadly correct, don't answer my question specifically.
My query is about variable declarations appearing between a function name and its block. OK, that's the original K&R style, but I still find the location of the declarations shocking. Having read the K&R Second Edition book that describes ANSI C89, I was aware that the previous style allowed a different way of declaring function parameters, but AFAIK that book did not show the declarations being made in this way. Maybe it does and I have forgotten about it.
I believe it is good to have a question separately about this particular issue in case someone else gets thrown by it in the future. My question should stand for anyone who can shed some light on how it was decided to allow the parameters be declared in this strange location. The impression you get from C and all C-inspired languages is that nothing comes between a token and its block braces. My question draws attention to a significant exception that should be highlighted and its rationalle understood, even if it is 30/40 years old.
Edit 2:
I now find that C++ syntax allows for a token to come between the function name and its block. Even so, the idea of whole declaration lines coming in between is more severe and worth pointing out to C newbies as a quirk they might encounter. I have checked, and the K&R Second Edition book indeed does not explicitly mention this.
It's not any variable, it's the function argument. Just another programming style, called K&R style.
Some additional read on this.
This syntax is deprecated since a long time but in C17 it is still valid. The removal of this feature has recently been voted into C2x, see point 6.30:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2451.pdf
In general the function definition is defined in the C Standard the following way
function-definition:
declaration-specifiers declarator declaration-listopt compound-statement
declaration-list:
declaration
declaration-list declaration
Such a function definition that contains the declaration-list is named as a function definition with an identifier list opposite to the function definition with a parameter type list.
So in the function declarator there is used a list of identifiers
void f(ipp)
^^^^
that need to be declared before the body of the function
void f(ipp)
int **ipp;
^^^^^^^^^
It is an old style of function definitions that is not recommended to use because such definitions do not provide a function prototype that can be checked by the compiler.
From the C11 standard:
6.7.6 Declarators:
1.direct-declarator (parameter-type-list)
2.direct-declarator (identifier-list)
As you can see, the standard specifies two ways of declaring functions.
The first involves typed parameters where each parameter is given a specific type.
The second involves an identifier list where parameter names are supplied inside the enclosing parenthesis without being given data types.
As a result, your code is valid C11 and compiles fine as it should be expected.
This question already has answers here:
Implicit function declarations in C
(6 answers)
Closed 4 years ago.
I recently found a bug in software related to the following warning:
warning: implicit declaration of function ‘my_func’ [-Wimplicit-function-declaration]
Despite the warning, the code was compiling and (most of the time) working.
My question is, what happens when the code is running and that function is called? Is that undefined behaviour, or can I assume that the function call is a no-op?
This usually indicates that the header file that declares this subroutine was not #included. When a subroutine is used without having been declared, many C compilers generate an implicit declaration. This behavior is a common cause of errors, because the compiler may generate incorrect code if the implicit declaration does not match the actual definition.
This link contains a sample. It may be helpful to understand your concern.
An implicitly defined function is assumed to return int and to take an arbitrary number of arguments. That may or may not be true for the real function.
Depending on your platform, the arguments may be passed in an unexpected way, e. g. in registers, via the stack, etc. And if the way of passing the arguments doesn't match the expectations, things go crazy.
The default function declaration in C has parameters of int.
So, if you do not declare the function, the compiler will assume it returns int and has all parameters of int.
However, you still need to define the function or the linker will give an error.
This question already has answers here:
Why is #include <stdio.h> not required to use printf()?
(3 answers)
Closed 5 years ago.
How this following code can run without including header file for printf function?
int main(){
printf("%d",1);
return 0;}
Note: This is a hand-wavy answer that will roughly be correct. Someone else who knows the gory details (for gcc, e.g.) may enlighten both of us. Here goes:
Because in C — at least for some compilers — implicitly defined functions are fine. So it compiles it, then hands it off to the linker. It sees a reference to printf, and since the linker by default links with the C runtime library, it will resolve that symbol to the correct function.
I guess an implicit function like that will get a default signature, typically expecting to return an int. As for the arguments to the function, those can't be type checked at compile time, because the compiler doesn't know what the actual function signature is. So it will just use standard calling convention, e.g. pass arguments by registers or something like that.
This question already has answers here:
Is it better to use C void arguments "void foo(void)" or not "void foo()"? [duplicate]
(6 answers)
in c: func(void) vs. func() [duplicate]
(2 answers)
Closed 8 years ago.
Having done most of my dev deeds in C++ and C#, I find the habit in C of specifying an empty parameter list with "void" a bit peculiar, but seeing it in "trustworthy sources" makes me assume it's required-ish. The question is why?
To clarify, in for instance Visual Studio, I cannot with any combination of enabled C compiler switches, and disabled C++ compiler switches, get even as much as a compiler warning when writing this:
void foo_bar();
Then, what is it that makes it necessary-ish to instead declare it with this:
void foo_bar(void);
Is it just old C standardese that is lingering that is not needed with later C standards?
Backstory:
When declaring functions in C (any symbol actually) you need declare everything in the proper order (declare a function before using it) otherwise you'll get errors regarding undefined symbols.
Forward declaration of functions allows you to accomplish this by declaring only the function signature (without the body). This allows the compiler to identify function names (symbols) and later use them before they are completely defined.
When using forward declarations to export the publicly accessible functions of a library (in your public header files) you will declare the entire signature so that users of your library will know what parameters are expected.
When using forward declarations for your own internal use you (sometimes) won't need to declare the entire signature of the function, only the return type and name will suffice -- no parameters. Only when you finally define the function will you specify the parameter list.
Direct answer:
Yes it's just old C standardese and nothing more. Because the same C standardese says that empty brackets means an unknown number of parameters (not necessarily 0).
Related reading:
This question I've asked some time ago tries to fathom (like you) the utility of declaring functions with "an unknown number of parameters" -- apparently in a very misconstrued way.