This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Error: No previous prototype for function. Why am I getting this error?
I have a function that I prototyped in the header file, however Xcode still gives me warning No previous prototype for the function 'printBind'. I have the function setBind prototyped in the same way but I do not get an warning for this function in my implementation.
CelGL.h
#ifndef Under_Siege_CelGL_h
#define Under_Siege_CelGL_h
void setBind(int input);
void printBind();
#endif
CelGL.c
#include <stdio.h>
#include "CelGL.h"
int bind;
void setBind(int bindin) { // No warning here?
bind = bindin;
}
void printBind() { // Warning here
printf("%i", bind);
}
In C, this:
void printBind();
is not a prototype. It declares a function that returns nothing (void) but takes an indeterminate list of arguments. (However, that list of arguments is not variable; all functions taking a variable length argument list must have a full prototype in scope to avoid undefined behaviour.)
void printBind(void);
That's a prototype for the function that takes no arguments.
The rules in C++ are different - the first declares a function with no arguments and is equivalent to the second.
The reason for the difference is historical (read 'dates back to the mid-1980s'). When prototypes were introduced into C (some years after they were added to C++), there was an enormous legacy of code that declared functions with no argument list (because that wasn't an option before prototypes were added), so backwards compatibility considerations meant that SomeType *SomeFunction(); had to continue meaning 'a function that returns a SomeType * but for which we know nothing about the argument list'. C++ eventually added the SomeType *SomeFunction(void); notation for compatibility with C, but didn't need it since type-safe linkage was added early and all functions needed a prototype in scope before they were defined or used.
Related
This question already has answers here:
What does an empty parameter list mean? [duplicate]
(5 answers)
Accessing the parameters passed to a function with an empty parameter list in C
(2 answers)
Closed 2 years ago.
I have been reading the difference between function() and function(void) in C, and I came to know that
an empty parameter list in a function declaration indicates that the
function takes an unspecified number of parameters
So I ran this code:
#include <stdio.h>
void fun();
int main(void)
{
fun(12, 13.22, 1234567890987654321, "wow", 'c');
}
void fun()
{
printf("What happened to those arguments?");
}
I don't understand why C allows this. All the posts I've read so far related to this say things like it's bad practice to use it, it is obsolescent, etc. Also from the above code, I think the type of those arguments is also unspecified. So I just want to know the reason behind "unspecified arguments of unspecified type":
What can be done with those arguments?
Is it possible to access those arguments within the function?
The reason for supporting the notation is historical. Before the first C standard (C89/C90), you couldn't use prototypes in C; prototypes were one of the biggest and most important features of Standard C. All function declarations, therefore, were written the 'empty parentheses' style (when they were written at all; most functions that returned int were not declared at all). The type void was also added in C89/C90, though some compilers supported it before the standard was finalized.
Because it was crucial to the success of C89/C90 that existing code should mostly continue to work, the empty parentheses style had to be allowed by the standard. So, your code might have been written in pre-standard C as:
#include <stdio.h>
int fun(); /* This declaration would probably have been absent */
int main(void)
{
fun(12, 13.22, 1234567, "wow", 'c');
return 0; /* This was required until C99 to give reliable exit status */
}
fun(i, d, l, s, c) /* No return type - implicitly returns int */
long l; /* Defined out of sequence - bad style, but legal */
char c; /* Passed as int; converted to char in function */
char *s; /* Should define all pointer arguments */
double d; /* No definition of i; it was an int by default */
{
printf("This is what happened to those arguments:\n");
printf("i = %d\n", i);
printf("d = %f\n", d);
printf("l = %ld\n", l);
printf("s = [%s]\n", s);
printf("c = %c\n", c);
/* No return statement - don't use the value from the function */
}
For the curious: you could omit the char *s; line in the function definition, and it still compiled and produced the same output. It was a bad idea to try that, though. You could replace the line int fun(); with static fun(); and the code compiles cleanly when no diagnostics are requested.
You get no warnings even now if you compile this file (old31.c) with GCC 9.3.0 using:
$ gcc -std=c90 -o old31 old31.c
$
Your example as written is skirting around the backwards compatibility provisions. Using void means it was new code (it would not have been valid in many pre-standard C compilers because it used void). And new code should not exploit the backwards-compatibility provisions without a good reason. That was true in 1991 as well as in the current millennium (but in 1991, there were a lot more good reasons to exploit the backwards-compatibility provisions). Good pre-standard code usually listed all parameters in the order they were used. Omitted definitions and out of sequence definitions were not entirely satisfactory.
You asked:
What can be done with those arguments?
In the code in the question, nothing can be done with the arguments. The caller pushes the values onto the stack, and pops them off when the function returns. The called function is unaware of their existence and can do nothing with them.
Is it possible to access those arguments within the function?
No — not using any standard mechanism.
There is a difference between a function declaration and a function definition when there is an empty parameter list.
Section 6.7.6.3p14 of the C standard states:
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. The empty list in a function
declarator that is not part of a definition of that function
specifies that no information about the number or types of the
parameters is supplied.
What this means is that this declaration:
void fun();
Means fun takes an unknown number of parameters. While this definition:
void fun()
{
printf("What happened to those arguments?");
}
Means that fun takes no parameters. So this function call:
fun(12, 13.22, 1234567890987654321, "wow", 'c');
Is invalid and invoked undefined behavior because the number of parameters in the call don't match the actual number of parameters. This is spelled out in section 6.5.2.2p6 regarding the function call operator ():
If the expression that denotes the called function has a
type that does not include a prototype, the integer promotions
are performed on each argument, and arguments that have
type float are promoted to double. These are called the default
argument promotions. If the number of arguments does not equal
the number of parameters, the behavior is undefined. If the
function is defined with a type that includes a prototype, and either
the prototype ends with an ellipsis (, ...) or the types of
the arguments after promotion are not compatible with the types of
the parameters, the behavior is undefined.If the function is
defined with a type that does not include a prototype, and
the types of the arguments after promotion are not compatible
with those of the parameters after promotion, the behavior is
undefined, except for the following cases:
one promoted type is a signed integer type, the other promoted type is the corresponding unsigned integer type,
and the value is representable in both types;
both types are pointers to qualified or unqualified versions of a character type or void.
As for why this is allowed, it is legacy behavior that goes back to pre-standardized versions of C where the type of variables and the return type of functions defaulted to int and the method of declaring functions differed from what they are now.
I am wondering why function prototypes are required by MISRA:2012. In the example below, the two prototypes aren't really necessary.
#include <stdio.h>
#include <stdlib.h>
// >>> Truly useless in my opinion
void display(void);
int main(void);
// <<<
void display(void) {
printf("Hello World!\n");
}
int main() {
display();
return EXIT_SUCCESS;
}
The rationale I can read on SO such as here isn't very clear to me. For instance, if main tries to access display before it is declared, the compiler or the static analyzer will raise an error: function display used before declaration.
In other words is it a good idea to create a deviation for this MISRA rule?
void display(void); is a function forward declaration. It has prototype format.
As indicated in the link posted, a function prototype is a function declaration with the types of all parameters specified. If there are no parameters, then the parameter list must be (void) (no parameters) and not () (any parameter).
The exact rule 8.2 says:
Rule 8.2 Function types shall be in prototype form with named parameters
The rationale provided (read it, it is pretty good) mentions that this is to avoid old K&R and C90 programs where not all parameters are specified. C99 still allows this at some extent, as long as the parameter types in the function declaration don't collide with the parameter types in the function definition.
Essentially, the rule seeks to ban these kind of functions:
void func1 (x) // K&R style
int x;
{}
void func2(x) // sloppy style
{}
All parameters (if any) must have types and names specified.
However, I find nothing in MISRA-C that requires you to write a function declaration for each function. This means that your example code would conform to this MISRA rule with or without the function declaration.
Though as I mentioned in a previous answer, writing .c files without function declarations (in prototype format) is sloppy practice. If your functions need to be called in a certain order, it should be made obvious by the program design, function naming and comments/documentation. Not by the order that they happen to be declared inside the .c file.
There should be no tight coupling between the source code line where a function is declared in the .c file and that function's behavior/use.
Instead, functions should be defined in an order that makes sense logically. A common way to write .c files is to keep all public functions, that have their function declaration up in the .h file, at the top of the .c file. Then let the internal functions (those with static/internal linkage) sit at the bottom. This model requires function declarations of all the internal functions. Another option is to put all internal functions on top, and the public functions at the bottom. As long as you are consistent, either is fine.
What's most important is that if function definitions inside the .c file are re-ordered, it should not break the program or cause compiler errors. The easiest way to ensure this is to always provide function declarations for every single function in your program.
Note that the function declarations on top of the file is not "truly useless" at all, as they provide a quick summary of all functions present in the C file. It is a way to write self-documenting code.
Note that the C standard allows no prototype for main(), as a special case.
Note that in addition, rule 8.7 and 8.8 disallows you to use void display(void) without static, since the function is only used in one translation unit.
If you do not declare the function, any function call will call default argument promotions for each argument because it is considered that the function has the semantics of the C89 standard.
Case 1:
Consider a call f(5), where the parameter of the function is of type double. The code of f will treat 5 as double, while the default arith promotions will pass only an integer.
A loss of header file that contains declarations may have your code pass integers and in fact the function to treat them as pointers causing seg faults. Here is a concrete example:
Case 2:
Suppose you want to use the function strtok and you do not include the header string.h with the declaration -- char *strtok(char *str, const char *delim)
Now you make the mistake to consider separator 'A' instead of "A". So if you forget the signature but keep in mind the meaning of parameters, if you do not include the header the code will compile with no warning and of course the code from strtok will consider your char 'A' (that is converted in an integer (=95)) as the actual argument. The code considers it is a pointer to a string and will try to access the pointer from the location 95 finishing with segfault.
Case 3:
Here is another typical example of code that segfaults on some architecture -- even if you do not make any mistake it still segfaults.
char *subtoken;
subtoken = strtok(str, delim, &saveptr);
In this case the function strtok (missing the declaration from string.h) is considered to return an int, so an implicit conversion from int->char* is made. If int is represented on 32 bits and the pointer on 64 bits, clearly the value of subtoken will be errorneous and will produce seg fault.
I don't understand what my error is:
void main(char string[])
{
strcpy(command_E,string);
processCMD(); /*FIRST ERROR: prototype function declaration not in scope */
}
void processCMD(void) /*SECOND ERROR: external item attribute mismatch */
{
.... /*rest of code not displayed*/
At the point where you use processCMD(), you haven't declared a prototype for it, so it gets a default one.
The fact that you haven't declared it causes the first error.
The fact that your actual definition conflicts with the default one created because you hadn't declared it is the cause of your second error.
The solution is to either define the function before use:
void processCMD(void) {
blah blah blah
}
void main (char string[]) { // not really a good definition for main, by the way.
strcpy(command_E,string);
processCMD();
}
or provide a prototype before use:
void processCMD(void);
void main (char string[]) { // not really a good definition for main, by the way.
strcpy(command_E,string);
processCMD();
}
void processCMD(void) {
blah blah blah
}
As to the declaration of main, the two canonical forms are:
int main (void);
int main (int argc, char *argv[]); // or char **argv.
Others are allowed by the standard (implementation defined) but those two are required (at least for hosted implementations - freestanding implementations like embedded systems or operating systems can pretty well do whatever they want).
You need a prototype before the the first use of the function to declare it so the compiler knows what kind of arguments the function takes (if any) and what it returns:
void processCMD(void); // prototype
void main(char string[])
{
strcpy(command_E,string);
processCMD();
}
void processCMD(void)
{
.... /*rest of code not displayes*/
Alternatively, you could defined the function before it's first use (since the definition will provide the information the compiler wants.
Typically, the prototype will go in a header file so other modules can use the function since function definitions can only be in one source file (barring such things as making the function static, which makes each instance of the function 'private' to a module, or marking the function as inline, which enables multiple definitions).
Some additional prototype trivia:
Generally in C, the lack of a protoype is not an error in itself - if the compiler sees a function call without having seen a prototype it will assume that you're passing the right parameters, it will apply 'default promotions' to paramters (basically convert things to int ot double as appropriate), and will assume the function returns an int. If those assumptions are wrong, then the program is incorrect and will have undefined behavior. Compilers can often be configured to emit warnings or errors for calling functions that don't have prototypes (apparently yours has). In C++, calling a function without a previous protoype being seen (or the full function definition) is always an error.
In C, there's a difference between:
void processCMD();
and
void processCMD(void);
The first is a function declaration, but not a prototype - it tells the compiler that processCMD is a function and that it returns void instead of int. But it doesn't tell the compiler anything about the arguments. The compiler will still allow function calls to be made with arguments passed and will apply the default promotions. (Again, this feature might be disabled by compiler configuration).
The second is a prototype that specifically tells the compiler that the function takes no arguments.
In C++, both are equivalent and specifically tell the compiler that the function takes no arguments.
This question already has answers here:
Are prototypes required for all functions in C89, C90 or C99?
(6 answers)
Closed 8 years ago.
I am kind of new to C (I have prior Java, C#, and some C++ experience). In C, is it necessary to declare a function prototype or can the code compile without it? Is it good programming practice to do so? Or does it just depend on the compiler? (I am running Ubuntu 9.10 and using the GNU C Compiler, or gcc, under the Code::Blocks IDE)
It is never required to declare a prototype for a function in C, neither in "old" C (including C89/90) nor in new C (C99). However, there's a significant difference between C89/90 and C99 with regard to function declarations.
In C89/90 it was not necessary to declare a function at all. If the function is not declared at the point of the call, the compiler "guesses" (infers) the declaration implicitly from the types of the arguments passed in the call and assumes that the return type is int.
For example
int main() {
int i = foo(5);
/* No declaration for `foo`, no prototype for `foo`.
Will work in C89/90. Assumes `int foo(int)` */
return 0;
}
int foo(int i) {
return i;
}
In C99 every function that you call must be declared before point of the call. However, it is still not necessary to declare it with a prototype specifically. A non-prototype declaration will work as well. This means that in C99 the "implicit int" rule no longer works (for inferred function return types, in this case), but parameter types can still be guessed from the argument types if function is declared without a prototype.
The previous example will not compile in C99, since foo is not declared at the point of the call. Yet, you can add a non-prototype declaration
int foo(); /* Declares `foo`, but still no prototype */
int main() {
int i = foo(5);
/* No prototype for `foo`, although return type is known.
Will work in C99. Assumes `int foo(int)` */
return 0;
}
...
and end up with valid C99 code.
Nevertheless, it is always a good practice to declare a prototype for the function before you call it.
An additional note: I said above that it is never required to declare a function prototype. In fact, for some functions it is a requirement. In order to properly call a variadic function in C (printf for example) the function must be declared with a prototype before the point of the call. Otherwise, the behavior is undefined. This applies to both C89/90 and C99.
In ANSI C (meaning C89 or C90), you do not have to declare a function prototype; however, it is a best practice to use them. The only reason the standard allows you to not use them is for backward compatibility with very old code.
If you do not have a prototype, and you call a function, the compiler will infer a prototype from the parameters you pass to the function. If you declare the function later in the same compilation unit, you'll get a compile error if the function's signature is different from what the compiler guessed.
Worse, if the function is in another compilation unit, there's no way to get a compilation error, since without a a prototype there's no way to check. In that case, if the compiler gets it wrong, you could get undefined behavior if the function call pushes different types on the stack than the function expects.
Convention is to always declare a prototype in a header file that has the same name as the source file containing the function.
In C99 or C11, standard C requires a function declaration in scope before you call any function. Many compilers do not enforce this restriction in practice unless you force them to do so.
it's not a must, if the function is defined before its use.
It is not required, but it is bad practice not to use prototypes.
With prototypes, the compiler can verify you are calling the function correctly (using the right number and type of parameters).
Without prototypes, it's possible to have this:
// file1.c
void doit(double d)
{
....
}
int sum(int a, int b, int c)
{
return a + b + c;
}
and this:
// file2.c
// In C, this is just a declaration and not a prototype
void doit();
int sum();
int main(int argc, char *argv[])
{
char idea[] = "use prototypes!";
// without the prototype, the compiler will pass a char *
// to a function that expects a double
doit(idea);
// and here without a prototype the compiler allows you to
// call a function that is expecting three argument with just
// one argument (in the calling function, args b and c will be
// random junk)
return sum(argc);
}
In C, if we do not declare a function prototype and use the function definition, there is no problem and the program compiles and generates the output if the return type of the function is "integer". In all other conditions the compiler error appears. The reason is, if we call a function and do not declare a function prototype then the compiler generates a prototype which returns an integer and it searches for the similar function definition. if the function prototype matches then it compiles successfully. If the return type is not integer then the function prototypes do not match and it generates an error. So it is better to declare function prototype in the header files.
C allows functions to be called even though they have not previously been declared, but I strongly recommend you to declare a prototype for all functions before using them so that the compiler can save you if you use the wrong arguments.
You should put function declarations in the header file (X.h) and the definition in the source file (X.c). Then other files can #include "X.h" and call the function.
Function prototype is not mandatory according to the C99 standard.
It's not absolutely necessary to declare a function for the calling code to compile. There are caveats though. Undeclared function is assumed to return int and compiler will issue warnings first about function being undeclared and then about any mismatches in return type and parameter types.
Having said that it's obvious that declaring functions properly with prototypes is a much better practice.
Select ‘Options’ menu and then select ‘Compiler | C++
Options’. In the dialog box that pops up, select ‘CPP always’
in the ‘Use C++ Compiler’ options.
Again select ‘Options’ menu and then select ‘Environment |
Editor’. Make sure that the default extension is ‘C’ rather than
‘CPP’.
This question already has answers here:
Is it better to use C void arguments "void foo(void)" or not "void foo()"? [duplicate]
(6 answers)
Closed 5 years ago.
When a C function does not accept any arguments, does it have to be declared/defined with a "void" parameter by the language rules?
PC-Lint seems to have problems when there's nothing at all in the argument-list, and I was wondering if it's something in the language syntax that I don't know about.
Edit: I just found a duplicate (back-dupe? it came first) question, C void arguments, which has more answers and explanations.
void means the function does not take any parameters. For example,
int init (void)
{
return 1;
}
This is not the same as defining
int init ()
{
return 1;
}
because in the second case the compiler will not check whether the function is really called with no arguments at all; instead, a function call with arbitrary number of arguments will be accepted without any warnings (this is implemented only for the compatibility with the old-style function definition syntax, pre-ANSI).
IIRC func(void) in C will declare a function that takes no parameters whereas func() declares a function that will take any number of parameters. I believe the latter is an artifact coming from pre-ANSI C.
According to Wikipedia here, the declaration func() does basically declare the function "without information about the parameters".