I am very new to programming and I always receive this error when defining functions:
The parameter IPWM_int has not been declared
There is no return type for the function, but it does not give any errors.
Here is the function that causes the problem (this is out of main() function):
int IntToASCII(IPWM_int)
{
uint8_t i;
for(i=0;i<5;i++)
{
IPWM_string[i]=0x30;
}
sprintf(IPWM_string,"%5d", IPWM_int);
return 0;
}
The correct function definition here is presumably (based on the %d formatting specifier and the variable name):
int IntToASCII(int IPWM_int)
The only way that this function definition could compile is if it were in ANSI C, and looked like this:
int IntToASCII(IPWM_int)
int IPWM_int;
{
[...]
Perhaps this explains why the code you adapted this from compiled?
You need to give the argument IPWM_int a type. It looks like you want IPWM_int to be the name of the parameter here so if this parameter is an int, for example, you would have:
int IntToASCII(int IPWM_int)
{
uint8_t i;
for(i=0;i<5;i++)
{
IPWM_string[i]=0x30;
}
sprintf(IPWM_string,"%5d", IPWM_int);
return 0;
}
int IntToASCII(int IPWM_int)
// ^^^ is required at function declaration and definition.
syntax:
return-type functionName(dataType arg1, datatype arg2, ....)
{
//function body
}
Related
I'm not arguing that this is good programming style, but I was surprised that this compiled[*] and ran without complaint:
#include <stdio.h>
// define function signature
typedef int (*proto_fn)();
int x() { return 22; }
// Note: type name and formal parameter name are the same
void printit(proto_fn proto_fn) {
printf("%d\n", proto_fn());
}
int main() {
printit(x);
return 0;
}
Aside from potentially confusing humans, is there anything in the C standard that would forbid using identical names for a type and a formal parameter?
[*] (In this case, Apple clang version 11.0.0 (clang-1100.0.33.8).)
I modified the code to check whether the name proto_fn stands for a type name or an variable of the type proto_fn, inside the function printit.
#include <stdio.h>
// define function signature
typedef int (*proto_fn)();
int x() { return 22; }
// Note: type name and formal parameter name are the same
void printit(proto_fn proto_fn)
{
printf("%d\n", proto_fn());
proto_fn;
}
int main() {
printit(x);
return 0;
}
Above code works fine.
#include <stdio.h>
// define function signature
typedef int (*proto_fn)();
int x() { return 22; }
// Note: type name and formal parameter name are the same
void printit(proto_fn proto_fn)
{
printf("%d\n", proto_fn());
proto_fn kk;
}
int main() {
printit(x);
return 0;
}
But this code throws an error :
error: expected ‘;’ before ‘kk’
proto_fn kk;
So, from this I concluded that the name proto_fn is just a variable of the type proto_fn, inside the function printit. I think the type proto_fn is not visible, inside the function printit . I think variable proto_fn shadows the type proto_fn inside the function printit. This might be the reason, why the code works.
Case A:
#include<stdio.h>
int divide( int a, b)
{ return 7; }
int main() {
int a=divide(8,3);
printf("%d",a);
return 0;
}
Case B:
#include<stdio.h>
int divide( a, b)
{
return 7;
}
int main()
{
int a=divide(8,3);
printf("%d",a);
return 0;
}
Why is Case A an error and Case B error free?
In Case B according to C99 standard, it assumes the variables to be of type int but then why not in case A, why is the type of b not considered to be of type int?
It looks like you are mixing old style argument list with new style argument list.
Old style is name only with 'int' assumed, new style is type and name.
For each additional name or type name a comma and the type and argument follows.
Additionally, for old style there should be declarations within the function for the argument types since they are not specified on the argument list.
This is in contrast to variables within the function which use commas to separate multiple variables of the same type, the functions' argument list uses commas to separate the list of arguments, each of which should be a type and name for new style.
eg:
int func(char arg1, long arg2, long arg3) {
char a,b,c=2,d;
long xPos,yPos;
...
}
vs:
int func(arg1, arg2, arg3) {
int arg1,arg2,arg3;
char a,b,c=2,d;
long xPos,yPos;
...
}
see also
C function syntax, parameter types declared after parameter list
I am learning C and I am studying functions. So, I read that when I implement my own function I have to declare it before the main(). If I miss the declaration the compiler will get an error message.
As I was studying this example (finds if the number is a prime number),
#include <stdio.h>
void prime(); // Function prototype(declaration)
int main()
{
int num, i, flag;
num = input(); // No argument is passed to input()
for(i=2,flag=i; i<=num/2; ++i,flag=i)
{
flag = i;
if(num%i==0)
{
printf("%d is not prime\n", num);
++flag;
break;
}
}
if(flag==i)
printf("%d is prime\n", num);
return 0;
}
int input() /* Integer value is returned from input() to calling function */
{
int n;
printf("\nEnter positive enter to check: ");
scanf("%d", &n);
return n;
}
I noticed that a function prime() is declared, but in the main, a function, input(), is called and also the function input() is implemented at the bottom. Ok, I thought it was a mistake and I change the name from prime to input.
However if I delete the declaration and I don’t put any there, the program is compiled without errors and it runs smoothly. (I compile and run it on Ubuntu.)
Is it necessary to declare a void function with not arguments?
If you don't have a forward declaration of your function before the place of usage, the compiler will create implicit declaration for you - with the signature int input(). It will take the name of the function you called, it will assume that the function is returning int, and it can accept any arguments (as Bartek noted in the comment).
For this function, the implicit declaration matches the real declaration, so you don't have problems. However, you should always be careful about this, and you should always prefer forward declarations instead of implicit ones (no matter if they are same or not). So, instead of just having forward declaration of the void prime() function (assuming that you will use it somewhere), you should also have a forward declaration of int input().
To see how can you pass any number of the arguments, consider this:
#include <stdio.h>
// Takes any number of the arguments
int foo();
// Doesn't takes any arguments
int bar(void)
{
printf("Hello from bar()!\n");
return 0;
}
int main()
{
// Both works
// However, this will print junk as you're not pushing
// Any arguments on the stack - but the compiler will assume you are
foo();
// This will print 1, 2, 3
foo(1, 2, 3);
// Works
bar();
// Doesn't work
// bar(1, 2, 3);
return 0;
}
// Definition
int foo(int i, int j, int k)
{
printf("%d %d %d\n", i, j, k);
return 0;
}
So, inside the definition of the function you're describing function arguments. However, declaration of the function is telling the compiler not to do any checks on the parameters.
Not declaring a prototype and relying on default argument/return type promotion is dangerous and was a part of old C. In C99 and onward it is illegal to call a function without first providing a declaration or definition of the function.
my question is, is it necessary to declare a void function with not arguments?
Yes. For this you have to put void in the function parenthesis.
void foo(void);
Declaring a function like
void foo();
means that it can take any number of arguments.
If prime is not used, then omit the declaration.
The code won't compile as C++, because the compiler would complain that function input is used but not declared. A C compiler might issue a warning, but C is more relaxed and does an implicit declaration of input as int input() which means that you can pass any value to input and input returns an int.
It is good style to always provide a function declaration before using the function. Only if you do this the compiler can see if you are passing too few, too many or wrongly typed arguments and how to correctly handle the return value (which might be short or char instead of int).
Is it possible to declare some function type func_t which returns that type, func_t?
In other words, is it possible for a function to return itself?
// func_t is declared as some sort of function pointer
func_t foo(void *arg)
{
return &foo;
}
Or would I have to use void * and typecasting?
No, you cannot declare recursive function types in C. Except inside a structure (or an union), it's not possible to declare a recursive type in C.
Now for the void * solution, void * is only guaranteed to hold pointers to objects and not pointers to functions. Being able to convert function pointers and void * is available only as an extension.
A possible solution with structs:
struct func_wrap
{
struct func_wrap (*func)(void);
};
struct func_wrap func_test(void)
{
struct func_wrap self;
self.func = func_test;
return self;
}
Compiling with gcc -Wall gave no warnings, but I'm not sure if this is 100% portable.
You can't cast function pointers to void* (they can be different sizes), but that's not a problem since we can cast to another function pointer type and cast it back to get the original value.
typedef void (*fun2)();
typedef fun2 (*fun1)();
fun2 rec_fun()
{
puts("Called a function");
return (fun2)rec_fun;
}
// later in code...
fun1 fp = (fun1)((fun1)rec_fun())();
fp();
Output:
Called a function
Called a function
Called a function
In other words, is it possible for a function to return itself?
It depends on what you mean by "itself"; if you mean a pointer to itself then the answer is yes! While it is not possible for a function to return its type a function can return a pointer to itself and this pointer can then be converted to the appropriate type before calling.
The details are explained in the question comp.lang.c faq: Function that can return a pointer to a function of the same type.
Check my answer for details.
Assume the function definition
T f(void)
{
return &f;
}
f() returns a value of type T, but the type of the expression &f is "pointer to function returning T". It doesn't matter what T is, the expression &f will always be of a different, incompatible type T (*)(void). Even if T is a pointer-to-function type such as Q (*)(void), the expression &f will wind up being "pointer-to-function-returning-pointer-to-function", or Q (*(*)(void))(void).
If T is an integral type that's large enough to hold a function pointer value and conversion from T (*)(void) to T and back to T (*)(void) is meaningful on your platform, you might be able to get away with something like
T f(void)
{
return (T) &f;
}
but I can think of at least a couple of situations where that won't work at all. And honestly, its utility would be extremely limited compared to using something like a lookup table.
C just wasn't designed to treat functions like any other data item, and pointers to functions aren't interchangeable with pointers to object types.
what about something like this:
typedef void* (*takesDoubleReturnsVoidPtr)(double);
void* functionB(double d)
{
printf("here is a function %f",d);
return NULL;
}
takesDoubleReturnsVoidPtr functionA()
{
return functionB;
}
int main(int argc, const char * argv[])
{
takesDoubleReturnsVoidPtr func = functionA();
func(56.7);
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef void *(*fptr)(int *);
void *start (int *);
void *stop (int *);
void *start (int *a) {
printf("%s\n", __func__);
return stop(a);
}
void *stop (int *a) {
printf("%s\n", __func__);
return start(a);
}
int main (void) {
int a = 10;
fptr f = start;
f(&a);
return 0;
}
It is not possible for a function to return itself by value. However it is possible itself to return by a pointer.
C allows to define function types that take undefined number of parameters and those those types are compatible with function types that take defined parameters.
For example:
typedef void fun_t();
void foo(int);
fun_t *fun = foo; // types are fine
Therefore the following function would work.
void fun(void (**ptr)()) {
*ptr = &fun;
}
And below you can find the exemplary usage:
#include <stdio.h>
void fun(void (**ptr)()) {
puts("fun() called");
*ptr = &fun;
}
int main() {
void (*fp)();
fun(&fp); /* call fun directly */
fp(&fp); /* call fun indirectly */
return 0;
}
The code compiles in pedantic mode with no warnings for C89 standard.
It produces the expected output:
fun() called
fun() called
There's a way, you just try this:
typedef void *(*FuncPtr)();
void *f() { return f; }
int main() {
FuncPtr f1 = f();
FuncPtr f2 = f1();
FuncPtr f3 = f2();
return 0;
}
If you were using C++, you could create a State object type (presuming the state machine example usage) wherein you declare an operator() that returns a State object type by reference or pointer. You can then define each state as a derived class of State that returns each appropriate other derived types from its implementation of operator().
I am trying to generate some numbers with the rand() function like below:
int main()
{
int i=0
for(i=0;i<20;i++)
{
printf("%f\n",rand_md());
}
return 0;
}
float rand_md()
{
return (float)rand()/(RAND_MAX+1.0);
}
But when I run gcc rand.c, I get the error like below:
rand.c: In function ‘main’:
rand.c:21: warning: format ‘%f’ expects type ‘double’, but argument 2 has type ‘int’
rand.c: At top level:
rand.c:36: error: conflicting types for ‘rand_md’
rand.c:21: error: previous implicit declaration of ‘rand_md’ was here
What's wrong with my code?
Best Regards,
When you use a function without declaring it first, C will assume it returns an int. To fix this, you have to declare the method signature for rand_md before you call it in main().
Add something like this before main or in a header file:
float rand_md();
double rand_md()
{
return (double )rand()/(RAND_MAX+1.0);
}
Now, rand_md returns a double instead of a float.
Also, since you haven't included it in your post, you should throw in a function prototype before main(). You also forgot to add a semicolon to int i = 0. The corrected code looks like this:
double rand_md();
int main()
{
int i=0;
for(i=0;i<20;i++)
{
printf("%f\n",rand_md());
}
return 0;
}
double rand_md()
{
return (double )rand()/(RAND_MAX+1.0);
}
You can use random(largest size of number) for this purpose.