passing char array as function parameters in C - c

I want to copy arr2 to arr and pass arr as a function paramater
void func(char * array)
{}
int main(void)
{
int a;
char arr[6][50];
char arr2[][50]={"qweeeaa","bbbb","ffaa","eeaa","aaaa","ffaa"};
for(a=0; a<6;a++)
{
strcpy(arr[a], arr2[a]);
}
func(arr);
return 0;
}
But I can not pass arr as a function parameter. I get
[Warning] passing argument 1 of 'func' from incompatible pointer type [enabled by default]
[Note] expected 'char *' but argument is of type 'char (*)[50]'
I am using MinGW GCC 4.8.1

The type you pass and the type the function expects do not match. Change the function to receive a pointer to an array:
void func(char (*array)[50])
{
}
Other problems:
1) You haven't declared a prototype for func() either. In pre-C99 mode, compiler would assume the function returns an int and this would cause problem.
In C99 and C11, missing prototype makes your code invalid. So either declare the prototype at the top of the source file or move the function above main().
2) Include appropriate headers (<stdio.h> for printf etc).

Related

Why does having an `int (*)(float)` point to an `int foo()` trigger a warning, but having an `int (*)(double)` point to it doesn't?

I have this piece of code:
int foo() { return 0; }
int main()
{
int (*float_function)(float) = foo;
}
When compiled using x86-64 GCC 12.2, with -Wall, it produces the warning (Link):
warning: initialization of 'int (*)(float)' from incompatible pointer type 'int (*)()' [-Wincompatible-pointer-types]
But, when I change from float to double (Link):
int foo(){ return 0;}
int main()
{
int (*double_function)(double) = foo;
}
The warning is now gone.
But I think that both of these should get a warning.
Am I wrong somewhere? Why does GCC not complain about the second example?
int foo() is declared without specifying its parameters. This is an obsolescent feature that lets you call it with any arguments. When calling the function, integer arguments are promoted to int (if needed), and float arguments are promoted to double.
Due to this, it's impossible for this function to receive a float parameter, which makes it incompatible with int (*)(float), but not with int (*)(double).
If you want a function that takes no parameters, declare it as int foo(void) which will make it incompatible with both.
Note that even with double, the code is not valid C because int foo() {...} is a function definition, so the compiler knows that it has no parameters (see chux's comment below for the standard reference). Most compilers still allow it.
If you replace it with a declaration int foo(); and place the definition elsewhere then the above is correct. In that case, the relevant standard quote (C17 6.7.6.3/15) is:
For two function types to be compatible, [...] If one type has
a parameter type list and the other type is specified by a function declarator that is not part of a
function definition and that contains an empty identifier list, [...] the type of each parameter shall be compatible with the type that results from the application of the default argument promotions.

In C, can you omit the parameter types of a function pointer when initializing it with the address of a declared function?

I'm trying to make sure I understand the syntax for function pointers in C. I know it's just a pointer to a specific type. That being said, why does the following code compile and print '10'?
(Note I'm using GCC 9.4.0 on Ubuntu 20.04)
void f(int);
void (*foo)() = f;
int main(){
foo(10);
return 0;
}
void f(int n){
printf("%d\n", n);
}
Shouldn't we at least get a compile time warning: initialization of 'void(*)()' with incompatible pointer type 'void(*)(int)'? Is foo getting initialized to void(*)(int) based on f?
If I change 'void f(int)' to 'void f(float)' I do get a warning. If I add 3 more int params to f e.g. void f(int, int, int, int) it still compiles and runs fine. If I make the last param a float, another warning.
The rules are the same for function pointer declarations as for function declarations ; and a pointer to function with empty parentheses parameter list is compatible with a pointer to prototyped function, if the return type matches.
In your example the issues are equivalent to:
void g();
int main()
{
g(10);
}
void g(int) { ..... }
The rules are: you can declare a function with empty parentheses and call it with arguments, but in the function call, certain conditions must be met and it is undefined behaviour with no diagnostic required if those conditions are not met.
One of the "certain conditions" is that you cannot have float as a parameter type in the function definition. Another is that the type and count of arguments must match the type and count of parameters in the function definition. To repeat, no diagnostic is required for any of this; your compiler is going above minimum requirements by warning about the incorrect parameter type float.
The type of the function pointer foo:
void (*foo)()
Is a pointer to a function taking an unspecified number of parameters and returning void. So a pointer to any function that has a return type of void (assuming no parameters are subject to promotion, i.e. char, short, float) is compatible with foo and can be assigned to it.
If you instead defined it like this:
void (*foo)(void)
This would generate an error for an incompatible pointer type, as foo points to a function that takes no arguments and returns void, and f does not match that.

typecast to (void *) when passing pointer to object

Consider the following snippet:
void my_func(int a, void *b);
...
struct my_struct s = { };
my_func(10, (void *)&s);
Is it necessary to typecast to (void *) when passing &s to the function?
A pointer to any type may be freely converted to or from a void * without a cast.
Section 6.3.2.3p1 of the C standard states:
A pointer to void may be converted to or from a pointer to any object
type. A pointer to any object type may be converted to a
pointer to void and back again; the result shall compare equal
to the original pointer.
The only time a cast is needed is if you pass a pointer to a variadic function like printf where an implicit conversion can't occur, since it won't know what the exact type being passed in is.
Note that, as with any pointer type, you can't "remove" a qualifier such as const when passing to a function without a cast. Sections 6.3.2.3p2 states:
For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type; the values stored in the original and converted pointers shall compare equal.
you do not have to with some exceptions as you may get the warning if the object which reference you pass to the function is volatile or const - generally has different attribute.
void ee(void *q)
{
pritntf("%p", q);
}
volatile int g;
const int f;
int main()
{
ee(&g);
ee(&f);
}
gives this warnings:
<source>: In function 'main':
<source>:17:8: warning: passing argument 1 of 'ee' discards 'volatile' qualifier from pointer target type [-Wdiscarded-qualifiers]
ee(&g);
^~
<source>:6:15: note: expected 'void *' but argument is of type 'volatile int *'
void ee(void *q)
~~~~~~^
<source>:18:8: warning: passing argument 1 of 'ee' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
ee(&f);
^~
<source>:6:15: note: expected 'void *' but argument is of type 'const int *'
void ee(void *q)
~~~~~~^
Compiler returned: 0
No, it is not required, it just makes the code clearer on what exactly is being passed to the function.

assignment makes pointer from integer without a cast [enabled by default] when assigning char pointer to character array

I'm trying to return a pointer to a character array. The function is located in a different file. I compile the files together and it prints out "hello" just fine, but still produces a warning
warning: assignment makes pointer from integer without a cast [enabled by default]
I tried casting the returned value of function() to (char *), but ended up with a different warning:
warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]" instead.
What am I doing wrong?
File 1
#include <stdio.h>
int main()
{
printf("%s\n", function());
return 0;
}
File 2
#include <stdio.h>
char *message = "hello";
char *function()
{
return(message);
}
The problem here is a missing prototype. For historical reasons C lets you use functions without declaring them. However, all such functions are considered returning int, and all their parameters are considered int as well.
Since your function returns char*, you need to add a prototype for it (it's a good idea to have prototypes for all your functions, including ones that indeed return an int):
#include <stdio.h>
char *function(); // <<== Add this line
int main()
{
printf("%s\n", function());
return 0;
}

pointer to a char

I have query on how to assign a pointer to a character
Sample program:
#include <stdio.h>
void main()
{
const char str1[]="MANCHESTER";
char *q;
q=str1;
*q='A';
printf("%s\n",q);
}
In the the above program, I am assigning a character pointer to string "str1",
When I compile the program with gcc, I get the below warning:
ptr3.c: In function ‘main’:
ptr3.c:7:3: warning: assignment discards qualifiers from pointer target type
I am not able to understand what the warning means.
warnings i get:
2: warning: return type of 'main' is not 'int'
: In function 'main':
7: warning: implicit declaration of function 'printf'
7: warning: incompatible implicit declaration of built-in function 'printf'
adding include stdio.h and return type int, fixes those.
#include <stdio.h>
int main()
{
char str1[]="MANCHESTER";
char *q;
q=str1;
*q='A';
printf("%s\n",q);
return 0;
}
edit:
i guess you should not declare the char array as const, if you plan on modifying it, directly or indirectly through another pointer

Resources