When I try to compile this I'm being told by gcc that I have conflicting types for pack_cui(C).
I don't see how I could be getting conflicting types as I know I'm passing in a char*. I'm new to C so I'm sure I'm missing something obvious.
int main(){
char* C = malloc(sizeof(char) * 4);
C[0] = 1;
C[1] = 2;
C[2] = -1;
C[3] = 4;
pack_cui(C);
return 0;
}
unsigned int pack_cui(char* C){
unsigned int new_int = 0;
unsigned int i;
for(i = 0; i < 4; i++){
new_int = new_int | (unsigned int)(signed int)C[i];
if(i != 3) new_int = new_int << 8;
}
return new_int;
}
The error I received was
hw12.c:17:14: error: conflicting types for ‘pack_cui’
unsigned int pack_cui(char* C){
^
hw12.c:13:5: note: previous implicit declaration of ‘pack_cui’ was here
pack_cui(C);
Add a prototype for pack_cui before main:
unsigned int pack_cui(char* C);
Otherwise, when the compiler sees the call to pack_cui, it has to guess the type, and in this case it guesses wrong.
When you call an undeclared function, the C89 standard mandates an implicit declaration. This declaration would be:
int pack_cui();
The () is not the same as (void), it indicates that the function takes an unspecified number of arguments, whereas (void) means zero. This is left over from pre-ISO/ANSI C, back in the K&R days.
You don't want that, because that is the wrong declaration. Create your own declaration at the top, above main():
unsigned pack_cui(char *);
Move the definition of pack_cui from below the main function, to above the main function. Or set up and include a header file that declares pack_cui.
Also, once this is done, recompile with warnings enabled, so that you catch the other issue with your code:
$ gcc -Wall foo.c
You should include stdlib.h, at least.
When you call a C function, whether it's one of your own or one declared by the standard library, you must have a visible declaration of that function so the compiler knows how to generate the code to call it. That declaration should be a prototype, i.e., a declaration that specifies the types of the function's parameters. A function definition (with the { ... } containing the code that implements the function) provide a declaration.
In your example, no declaration of pack_cui is visible at the point of the call; it's not defined until later.
You can fix this by moving the definition of pack_cui above the definition of main, or by adding a "forward declaration" and leaving the definitions where they are.
The latter would look like this:
unsigned int pack_cui(char* C); /* a declaration, not a definition */
int main(void) { /* definition of main */
/* ... */
}
unsigned int pack_cui(char* C) { /* definition of pack_cui */
/* ... */
}
Either approach is acceptable.
For much the same reason, you need to provide a declaration for the malloc function. You should do this by adding
#include <stdlib.h>
to the top of your source file.
Related
I've learned function pointer is used as :
double (*ptr)(double)
ptr = my_func1;
And also, using 'typedef' could be
typedef double (*func1)(double);
func1 my_func1;
But I can't understand why this code is valid below :
int main(void){
test(a);
}
void test(int f(int))
{\
int x;\
(f==a)?(x=1):(x=2);\
printf("%d",f(x));\
}
What's that int f(int)? Is it same syntax with function pointer?
I know the type int (*)int is valid, but I've never seen the type int (int).
And Also I can't understand why the syntax in the main fuction "int f(int) = func_1" is invalid but in the 'test' function's parameter int f(int) = a is valid.
Please tell me TT Thank you.
int f(int) is a function declaration.
In C, two kinds of entities cannot be passed into functions, returned from functions or assigned: arrays and functions.
If parameters of these types are declared, they are silently turned into pointers.
A parameter int f(int) is changed to mean int (*f)(int), similarly to the way a parameter int a[3] is changed to int *a.
You might see a gratuitous warning if you declare a function one way, but define it the other; e.g.:
void test(int (*)(int));
void test(int f(int))
{
}
I've seen some version of GCC warn about this, even though it is correct; the definition and declaration are 100% compatible.
Because inside test, f is declared as a pointer, it is assignable:
f = some_func
However, in a situation where int f(int) declares a function, the identifier is not assignable:
{
int f(int); // "There exists an external f function" -- okay.
f = some_func; // Error; what? You can't assign functions!
}
Outside of function parameter declarations, functions and pointers to functions are distinguished in the usual way, as are arrays and pointers.
I am trying to run the code below and i am getting the error messages below.
Program:
int main()
{
int (*res)[3],i;
res=func();
}
int (*func())[3]
{
static int arr[3][3]={1,2,3,4,5,6,7,8,9};
return arr;
}
Error:
PointerTo1D.c: In function ‘main’:
PointerTo1D.c:6:5: warning: assignment makes pointer from integer without a cast [enabled by default]
res=func();
^
PointerTo1D.c: At top level:
PointerTo1D.c:11:7: error: conflicting types for ‘func’
int (*func())[3]
^
PointerTo1D.c:6:6: note: previous implicit declaration of ‘func’ was here
res=func();
Could someone please help me out here???
res is a pointer to an array with 3 elements of int
int (*func())[3]: func is a function which returns a pointer to array with 3 elements of int
Because there is no prototype for function func() you got:
warning: implicit declaration of function 'func'
res=func();
which means that compiler use default prototype int func().
There is next warning:
warning: assignment makes pointer from integer without a cast [enabled by default]
res=func();
because default prototype is used, compiler assumes that function func() returns int which is than assigned as a pointer to res which is the pointer
When code for function func() is reached you get error:
error: conflicting types for 'func'
int (*func())[3]
Solution is to provide proper prototype before main.
int (*func())[3];
int main()
{
...
}
Update: There is also warning:
warning: missing braces around initializer [-Wmissing-braces]
static int arr[3][3]={1,2,3,4,5,6,7,8,9};
It is better to use:
static int arr[3][3]={{1,2,3}, {4,5,6}, {7,8,9}};
You have to change your code to
int** func() //change here
{
static int arr[3][3]={1,2,3,4,5,6,7,8,9};
return arr;
}
and
int** func(); //forward declaration
int main()
{
int ** res = NULL,i = 0; //change here
res=func();
return 0;
}
Any function you call from your main() should either be defined before main() or atleast have a forward declaration before main() so that the comipler has a way to know the function signature before the function is used (called).
Note: Usually, it's not a good practice to use static for this purpose. Dynamic memory allocation (malloc()/calloc()) is designed exactly for this purpose.
First if you want to return a pointer do like this :
(int **)func() {
...
return arr;
}
Then define res like this :
int ** res;
res = func();
If a function is called without a declaration being visible, it is assumed to be old-style declared, with external linkage, and returning an int in C89:
extern int func();
The empty parentheses (an old-style declaration) mean: No argument checking required, function takes fixed number of default-promoted arguments.
In C99, implicit declarations have been removed, Gcc warns about them by default, but sticks to the old behaviour, probably for backward compatibility. They can be turned into errors for example with gcc -std=c99 -pedantic-errors, or gcc -std=gnu89 -Werror=implicit-function-declaration if you want to stick to GNU89 (what I suspect was specified from the warnings given).
To fix the problem, the function needs at least to be declared before use:
int (*func())[3];
int main() {
func();
}
This still uses old-style declarations, marked obsolescent in all C standards, I'd suggest using prototypes to ensure argument checking:
int (*func(void))[3];
int main(void) { /* ... */ }
I was making a simple C program
#include<stdio.h>
static int a;
a = 5;
int main()
{
printf("%d",a);
return 0;
}
Compiler error: "non static declaration of 'a' follows static declaration"
What does this error mean?
what this error log means?
It is a little tricky: what looks like an assignment
a = 5;
is treated as
int a = 5;
due to an old C rule that allowed you to declare int variables and int-returning functions without specifying their type explicitly (this is definitely not a good idea in the modern version of C).
Note that this is treated as a declaration with an implicit int only in the scope outside a function body.
You can fix it by combining the declaration with initialization, like this:
static int a = 5;
Outside a function you can only declare variables, you cannot have actual code statements.
a = 5;
is being interpreted as another declaration, when your intent I think is to write some code.
instead declare and initialise a at the same time
static int a = 5;
Your first declaration of a is static (ahas internal linkage).
The second declaration is not static (a has external linkage). Yes, a = 5; is a declaration with implicit type int in this case.
Both do not agree.
Btw. for functions this would be o.k. because the second declaration would "inherit" the internal linkage.
We cannot write any assignment statement globally. For example:
#include <stdio.h>
static int i=10; //Initialization statement
i=25; //Assignment statement
int main(){
printf("%d",i);
return 0;
}
Output: Compilation error
Note: Assigning any value to the variable at the time of declaration is known as initialization while assigning any value to variable not at the time of declaration is known assignment.
You can't set value as you did it: a = 5; before main(...). See code below:
static int a = 1; //default = 0;
int main()
{
printf("a = %d\n", a);
a = 2;
printf("a = %d\n", a);
return 0;
}
Output:
a = 1
a = 2
A = 5 is considered as an attempt to create another variable called a. You should put the = 5 after static int a.
Static int a = 5;
Just a little modification to your code will help you to understand it.
#include<stdio.h>
//static int a; //comment this statement
a = 5;
int main()
{
printf("%d",a);
return 0;
}
now compile this code [please enable your compiler's warnings]
Then you will get a warning something like this
data definition has no type or storage class [enabled by default]
So now try to understand this warning it means that compiler treat statement a=5 as a definition but without data type. But compiler unable default data type that is int.
so this statement is equivalent to
int a=5;
for( k = 0; k < CycleCount;k++)
{
//make Org data
int* Data = MakeData(DataCount[i]);
......
the function look like this one.
i think this is right. so ...
int* MakeData(int DataCount)
{
//
int* Data=(int*)malloc(DataCount*sizeof(int));
int i;
for( i=0; i<DataCount; i++)
{
//
Data[i] = rand()%DataCount +1;
}
return Data;
}
i dont know why this didn't work.
what shoud i have to do???
When the C compiler finds a function call without having seen a function prototype it assumes a function that returns an int.
You should tell the compiler the correct function signature with the "function prototype":
int* MakeData(int DataCount);
This should be placed in a .h file that will be included in all compilation units that call or define the function.
If you have a static function, that is visible only in the current compilation unit, you can place the prototype (incl. static) before all functions in that file.
Further you should never cast the return from malloc. It returns a void*. In the language C this can be converted to any other pointer type. You get the correct prototype when you #include <stdlib.h>.
The following code displays an error if the Storage Class of the parameters of the function int *check(register int,register int); declared as some other Storage Class.
I compiled this code on Code::Blocks 10.05 IDE with GNU GCC Compiler. What is the reason behind the error? Is it a compiler specific error or a general one?
The code section begins from here:
int *check(register int, register int);
int main()
{
int *c;
c = check(10, 20);
printf("%d\n", c);
return 0;
}
int *check(register int i,register int j)
{
int *p = i;
int *q = j;
if(i >= 45)
return (p);
else
return (q);
}
int *check(register int i,register int j)
{
int *p=i;
int *q=j;
Type mismatch of p q and i j. Perhaps what you want is :
int *check(int i, int j)
{
int *p=&i;
int *q=&j;
Correction: Note that register cannot be used with &. Besides, the keyword register has little usage because the compiler usually ignores it and does the optimization itself.
int *check(register int i,register int j)
{
int *p=i;
int *q=j;
if(i >= 45)
return (p);
else
return (q);
}
While register storage class specifier is allowed on parameter declaration, parameters i and j have int type while p and q are of type int *. This makes the declaration of p and q invalid.
You cannot just change this to:
int *p=&i;
int *q=&j;
as the & operator does not allow you to have an operand of register storage class.
You cannot also also change the parameter declaration from register int i and register int j to int i and int j and then return the address of i and j object as their lifetime ends at the exit of the function.
In your case you should just not use pointers: use int parameters and an int return value.
First type mismatch:
int *p=i;
int *q=j;
Second side note & not applied/valid on register variables.
From: address of register variable in C and C++
In C, you cannot take the address of a variable with register storage. Cf. C11 6.7.1/6:
A declaration of an identifier for an object with storage-class specifier register
suggests that access to the object be as fast as possible. The extent to which such
suggestions are effective is implementation-defined.
third: Returning address of local object is Undefined behavior (and parameters of functions counts in local variables). Don't return address of that there life is till function returns.
Suggestion:
To return address, you need to do dynamic allocation and return address of that. for example:
int *check(int i,int j){
int *p= malloc(sizeof (int));
int *q= malloc(sizeof (int));
*p = i;
*q = j;
if(i >= 45){
free(q);
return (p);
}
else{
free(p);
return (q);
}
}
Note returned address is not of i, j, but its address of dynamically allocated memory. Don't forget to call free(a) in main().
In my machine with GCC 4.7.3 on Ubuntu 13.04, the output is
$gcc test.c
test.c: In function ‘main’:
test.c:7:3: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
test.c:7:3: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
test.c: In function ‘check’:
test.c:13:12: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:14:12: warning: initialization makes pointer from integer without a cast [enabled by default]
$./a.out
20
It accepts the program with a lot of warnings. And there is not a single word says "storage class". so I wonder what version of GCC you are using?
The first two warnings can be fixed by #include <stdio.h> and change %d in the printf function call to %p. Let's ignore those for now and focus on the rest two. Depends on what you want to do, you can have different options to eliminate them.
If you want to return the address of i or j as a stack based variable (which is unusual because it is invalid after return to the caller), you can do
int *check( int i, int j)
{
int *p = &i;
int *q = &j;
...
You cannot obtain the address of a register variable, so you have to remove them. In this case, with your main function your program will print something like 0x7fffc83021f8 in my machine. That is the pointer value to the variable j, although it is not valid at the time we prints it, as long as you do not attempt to dereference it everything is OK.
If this is not what you want, you probably want to force the integer i or j to represent a pointer, then you need to do
int *check(register int i,register int j)
{
int *p=(int *)i;
int *q=(int *)j;
if(i >= 45)
return (p);
else
return (q);
}
Note in this case the use of register keyword is OK although it may have very limited effect. Also this would still warn you when you compile the code in some machine (especially 64 bit GCC).
Although strange, but this code have some sense: usually an integer that too close to zero is not a valid pointer.
So what this code does is: it returns i's value as a pointer if it's a valid pointer(value greater than 45), or return js value. The result in this case is 0x14 (remember we need to replace %d to %p, so the output is in hexadecimal).
EDIT
After look at your main function I believe what is wanted here would be
int check(register int i,register int j)
{
int p=i;
int q=j;
if(i >= 45)
return (p);
else
return (q);
}
But anyway this code can be simplified as
int check(register int i,register int j)
{
if(i >= 45)
return i;
else
return j;
}
or even
int check(register int i,register int j)
{
return i>=45 ? i : j;
}
in these cases the main function should be
int main()
{
int c;
c = check(10, 20);
printf("%d\n", c);
return 0;
}
Note since the data type of c is now int so the %p for printf is restored back to %d. The output is the same of the original code: 20.
OK now I see what you are asking.
If you have a function prototype declaration like this:
int *check(register int, register int);
As soon as the compiler sees this, it can enforce a rule that no code will attempt to obtain the address of the parameters. It is up to the compiler to consider a consistent way to generate code for function calls through out the program based on this fact. This may or may not be the same as
int *check(int, int);
Which performs the default treatment of parameters (but again the compiler will ensure it is consistent through out the program).
But consider the following:
int *check(auto int, auto int);
The compiler do not know weather the address of the parameter is going to be used or not unless it sees the actual implementation. So it cannot assume anything. The programmer obviously want some optimization, but the compiler do not have any further information to do so.
So it does not make sense to specify a parameter to be auto.
What if use auto for parameters of function definition? Again this makes little sense. The compiler can have a strategy that if there is no attempt to obtain the parameter address then treat it as register other use stack for it. But for parameters that do not use auto the rule would be the same. So it does not gives the compiler any further information.
Other storage classes are even makes no sense for parameters in function definition. It is not possible to pass a parameter through static data area or the heap (you can only pass pointers - which actually in the stack or registers).