implicit declaration of function 'enterChar' [-Wimplicit-function-declaration] [duplicate] - c

This question already has answers here:
Message "warning: implicit declaration of function"
(10 answers)
Closed 2 years ago.
I have two questions here regarding my C program:
1) In main(), the lines C = enterChar();, N = enterNum();, leftJustifiedPic(C, N);, rightJustifiedPic(C, N); are all giving me implicit declaration of function. What does that even mean? I'm used to Java and is it a little bit different in C with regards to the code?
2) In method enterChar(), Im getting conflicting types for 'enterChar' error and again do not understand what it means and why it happens. I'm working on Eclipse (Cygwin-GCC) if it has anything to do with the problem.
Could smb please detail me on this types of errors and warnings? I appreciate it!
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Welcome to the menu!");
printf("The menu is:\n1. Enter/Change Character\n2. Enter/Change Number\n3. Print Triangle Type 1(Left Justified)\n4. Print Triangle Type 2(Right Justified)\n5. Quit");
printf("\n");
printf("Now enter a number from the menu from 1 through 5: \n");
int num = 0;
scanf("%d", &num);
char C;
int N = 0;
switch(num){
case 1:
C = enterChar();
break;
case 2:
N = enterNum();
break;
case 3:
leftJustifiedPic(C, N);
break;
case 4:
rightJustifiedPic(C, N);
break;
default:
printf("Smth is wrong!");
}
return 0;
}
char enterChar(){
printf("Enter your input as a character. Only 'C' and 'c' are allowed!\n");
char input = 0 ;
scanf("%c", &input);
while(input != 'c' || input != 'C'){
if(input != 'C' || input != 'c'){
printf("You have to enter 'C' or 'c'. Try again!");
}
}
return input;
}

1) You haven't declared the functions before you use them, and the dialect of C that you are using has "implicit function declarations". This means the function are implicitly declared to return int and take any number of parameters of any type.
2) Because you have an implicit function declaration int enterChar(), that clashes with the definition char enterChar().
The solution is to provide function declarations before main().
char enterChar(); // and other function declarations
int main(void) {
....
}
// function definitions
char enterChar() { .... }
Depending on your use-case, it may be worth investigating using a more recent version of C, which doesn't have these implicit function declarations (e.g. C99 or C11)

When the prototype of a function is not declared, the compiler assumes that the return type is an int.
That is what it calls an implicit declaration.
and then, you go to declare enterChar that returns a char. Since the compiler had used an implicit declaration when it was called it in main, it complains about the conflicting types.
You can resolve that problem by providing an explicit declaration of the function before using it in main.
char enterChar();
It's a good practice to provide explicit declarations of all functions before they are used.

Functions must at least be declared before they are called; if possible, they should be defined before they are called.
When the functions are defined in the same source file from which they are called, move the definition of the function to precede the caller, like so:
char enterChar( void ) // void indicates function takes no arguments
{
// body of enterChar
}
int enterNum( void )
{
// body of enterNum
}
int main( void )
{
...
c = enterChar();
...
N = enterNum();
...
}
Yes, this makes the code read "backwards", but it eliminates some headaches.
When functions are defined in a different source file from which they are called, make sure you have a declaration of that function (using prototype syntax!) in place before the call. The declaration may appear at file scope (outside of any function), or within the function from which the call is made:
// enterChar and enterNum are *defined* in a different source file
int enterNum( void ); // declaration at file scope, valid for remainder
// of file
int main( void )
{
char enterChar( void ); // declaration within a block, only valid for
// duration of current block
...
c = enterChar();
...
}
In the case above, the declaration of enterNum is valid over the entire file, while the declaration for enterChar is only valid within the body of main; if any other function in the same source file wants to call enterChar, it must also have a declaration before the call. Either way, the declaration must precede the call.
The usual practice for handling declarations of functions defined in a different source file is to create a header file which contains the function declarations (not definitions!) and include that header in the file that defines the calling function(s):
/**
* main.c
*/
#include <stdio.h>
#include "utils.h" // contains declarations for enterChar and enterNum
int main( void )
{
...
c = enterChar();
...
N = enterNum();
}
Header file:
/**
* utils.h
*/
#ifndef UTILS_H // Include guard; prevents header file from being processed
#define UTILS_H // more than once per translation unit
char enterChar( void ); // void in the argument list indicates the function takes no arguments
int enterNum( void ); // an empty argument list in a declaration specifies that
// the function takes an *unspecified* number of arguments
// which is not the same thing, and not necessarily safe
#endif
Implementation file:
/**
* utils.c
*/
#include <stdio.h>
#include <stdlib.h>
#include "utils.h" // including our own header to make sure our declarations
// and definitions line up.
char enterChar( void )
{
// body of enterChar
}
int enterNum( void )
{
// body of enterNum
}
You'll notice that utils.c also includes utils.h. This is to make sure that our declarations and definitions are in sync.

You have "forward references" to undeclared functions. They need a function prototype, or implementing before being called. Without knowing what the function takes or returns, the compiler assumes int types, although I suspect some compilers will flag an error anyway.
You only posted one function, so I limit my example to that.
#include <stdio.h>
#include <string.h>
char enterChar(); // function prototype
int main(void)
{
char C;
//...
C = enterChar(); // function call
//...
return 0;
}
char enterChar() // function implementation
{
char input = 0;
//...
return input;
}

Related

why can not malloc in global but can use inline function for malloc [duplicate]

This question already has answers here:
Error "initializer element is not constant" when trying to initialize variable with const
(8 answers)
Closed 2 years ago.
Hi i have a test code for calling malloc as below:
#include <stdio.h>
#include <stdlib.h>
int *p;// = (int*)malloc(sizeof(int));
int main() {
//...
}
Of course this code will be fail when compile with the error: initializer element is not constant and i have referenced this question: Malloc function (dynamic memory allocation) resulting in an error when it is used globally. They said that we have to use malloc() in side a function. But if i change my code to:
#include <stdio.h>
#include <stdlib.h>
int *p;
static int inline test_inline(int *x) {
printf("in inline function \n");
x = (int*)malloc(sizeof(int));
return x;
}
test_inline(p);
int main(){
//...
}
As the definition of inline function: "Inline Function are those function whose definitions are small and be substituted at the place where its function call is happened. Function substitution is totally compiler choice." So this mean we can substitute the inline function test_inline in above example with the code inside it and it means we have call malloc() in global ? Question 1: is this wrong about inline or malloc() ?
Question 2: In the link i give about malloc function dynamic there is an answer said that "Not only malloc, u can't call any function as you have called here. you can only declare function as global or local there" but i see that we still can call function in global and in global we can initialization not only declaration as below:
#include <stdio.h>
#include <stdlib.h>
int b;
b = 1;
int test() {
printf("hello");
}
test();
int main() {
//...
}
So this mean in the global we still can declaration and initialization and call function. But when we compile the above code it has a warning that warning: data definition has no type or storage class So why we have this warning with variable b ? I do not see any thing which inconsequential here. And with the line test(); i have call a function outside main(), i know this make no sense because we never run test() but i have no problem, stil build success. So back to question 1 about the malloc(), i think with the answer that "we can not call a function in global or can not initialize", i think it is not true. Is there any explain more reasonable?
Please refer to the comments.
#include <stdio.h>
#include <stdlib.h>
int b;
b = 1; //this is only allowed, because the previous line is a tentative definition. [1]
int test() {
printf("hello");
}
test(); // this is taken as a function declaration, not a function call [2]
int main() {
//...
}
Case [1]:
Change you code to
int b = 5; // not a tentative defintion.
b = 1; // this assignment is not valid in file scope.
you'll see an error.
Case [2]:
If the signature of the function differs, you'll again see an error. Example: try the below:
float test( int x ) {
printf("hello");
return 0.5;
} //return changed to float, accepts an int as paramater.
test(); //defaults to int and no parameter - conflict!!
this will produce the error for conflicting types.
So, bottom line, no assignment, function call - all in all, no code that needs to execute at runtime, can be put into file scope. The reason behind that being, unless it's contained in a function that's called from main(), there's no way to know when / how to execute it.
You're not calling functions "globally".
Taking your example:
#include <stdio.h>
#include <stdlib.h>
int b;
b = 1;
int test() {
printf("hello");
}
test();
int main() {
//...
}
In C types default to int.
So the lines
int b;
b = 1;
are basically
int b;
int b = 1;
and the lines
int test() {
printf("hello");
}
test();
are just
int test() {
printf("hello");
}
int test(); // -> this is just a matching declaration
Have a look at:
https://godbolt.org/z/3UMQAr
(try changing int test() { ... to char test() { ... and you get a compiler error telling you that those types don't match)
That said, you can't call functions there. Functions are called at runtime by your program (especially malloc, which is asking your OS to allocate memory for you). I'm not a C expert here but as far as I know C doesn't have constexpr functions, which would be the only "exception".
See: Compile-Time Function Execution
Question 1: is this wrong about inline or malloc()
kind of: malloc does have to be called in a function, but the variable it works on can be declared global. i.e. int *pointer = NULL;//global scope
then pointer = malloc(someByteCount);//called within function. Now, pointer is still global, but also has a memory address pointing to someByteCount bytes of memory.
Question 2: In C, all functions are defined on the same level of a .c file, just like main(void){...return 0}, but all functions (except main(void)) must be called within the {...} of other functions, so in short, functions cannot be called from global space.
Illustration for Q2:
//prototypes
void func1(void);
void func2(void);
void func3(void);
int main(){
int val = test_inline(p);//...
}
int main(void)
{
//legal
func1();
func2();
func3();
return 0;
}
//not legal
func1();
func2();
func3();
//definitions
void func1(void)
{
return 0;
}
void func2(void)
{
return 0;
}
void func3(void)
{
return 0;
}
Errors in syntax of your example (see comments):
int *p = NULL;//initialize before use
static int inline test_inline(int *x) {
printf("in inline function \n");
x = (int*)malloc(sizeof(int));
printf("%p\n", x);
return 0;
//return x;//function returns int, not int *
}
//... test_inline(p);//must be called in a function
int main(void){
int val = test_inline(p);//function declaration returns int, not pointer
return 0;
}
This code compiles, and runs, but as noted in comments, usefulness may be lacking.
Question 1: is this wrong about inline or malloc() ?
Neither. Your understanding of inline is incorrect. The function call may be replaced with an inline expansion of the function definition. First, let's fix the function definition because the return type int doesn't match the type of what you're actually returning:
static inline int *test_inline( int *x )
{
printf( "in inline function\n" );
x = malloc( sizeof *x );
return x; // x has type int *, so the return type of the function needs to be int *
}
If you call this function like so:
int main( void )
{
int *foo = test_inline( foo );
...
}
what the compiler may do is substitute the function call with the assembly language equivalent of the following:
int main( void )
{
int *foo;
do
{
printf( "in inline function\n" );
int *x = malloc( sizeof *x );
foo = x;
} while( 0 );
...
}
Nothing's happening "globally" here. The substitution is at the point of execution (within the body of the main function), not at the point of definition.
Question 2: In the link i give about malloc function dynamic there is an answer said that "Not only malloc, u can't call any function as you have called here. you can only declare function as global or local there" but i see that we still can call function in global and in global we can initialization not only declaration as below:
In the code
int test() {
printf("hello");
}
test();
the line test(); is not a function call - it's a (redundant and unnecessary) declaration. It does not execute the function.
Here are some excerpts from the language definition to clarify some of this:
6.2.4 Storage durations of objects
...
3 An object whose identifier is declared without the storage-class specifier
_Thread_local, and either with external or internal linkage or with the storage-class
specifier static, has static storage duration. Its lifetime is the entire execution of the
program and its stored value is initialized only once, prior to program startup.
Bold added. Any variable declared outside the body of a function (such as p in your first code snippet) has static storage duration. Since such objects are initialized before runtime, they cannot be initialized with a runtime value (such as the result of a function call).
6.7.4 Function specifiers
...
6 A function declared with an inline function specifier is an inline function. Making a
function an inline function suggests that calls to the function be as fast as possible.138)
The extent to which such suggestions are effective is implementation-defined.139)
138) By using, for example, an alternative to the usual function call mechanism, such as ‘‘inline
substitution’’. Inline substitution is not textual substitution, nor does it create a new function.
Therefore, for example, the expansion of a macro used within the body of the function uses the
definition it had at the point the function body appears, and not where the function is called; and
identifiers refer to the declarations in scope where the body occurs. Likewise, the function has a
single address, regardless of the number of inline definitions that occur in addition to the external
definition.
139) For example, an implementation might never perform inline substitution, or might only perform inline
substitutions to calls in the scope of an inline declaration
All this means is that the inlined code behaves like it was still a single function definition, even if it's expanded in multiple places throughout the program.

Unable to return function parameter due to conflicting types for 'function' in C

I'm new to C and I'm trying to understand how there are conflicting types for my function "using_name".
I also don't understand why I have to include a '*' to name the 'using_name()' function. It is because I'm storing a value in the function address?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int using_name(), call_func(char name[20]);
char name[20];
int main ()
{
using_name();
call_func(name);
return 0;
}
char* using_name()
{
printf("What is your name: ");
scanf("%s", name);
printf("\n Your name is %s", name);
return name;
}
int call_func(char name[20])
{
printf("Hello %s", using_name(name));
}
Error: conflicting types for 'using_name'
The return and argument types in the funnction prototype at the beginning of the program has to match the actual types when the function is defined later.
Since using_name() is defined as:
char *using_name()
You need to change the earlier prototype to:
char *using_name();
int call_func(char name[20]);
Another solution is to just put the function definitions at the beginning of the program. You only need prototypes for functions that are used before they're defined, or functions that are defined in another compilation unit (although these prototypes are usually put in a header file).

why does the compiler give a warning for unused function?

I have just written a sample program to understand the working of functions in C. I declared a function in C and call it during my programs execution. However my compiler gives me a warning saying unused function. My code looks like this :
#include <stdlib.h>
#include <stdio.h>
int test_function(x);
int main(){
int x;
char letter[] ={"HAAA"};
char cmpre[] = {"AHD"};
int value;
for(int i=0; i<4;i++)
{
if(letter[i] == cmpre[i])
{
x=0;
}
}
int test_function(x)
{
if (x==0)
{
printf("the letters are the same");
}
return value;
}
printf("To check if the letters are the same go to the function");
test_function(x);
return 0;
}
The program seems to execute fine but I get a warning in the fourth line where I declared the function in the start of the program. The warning is :
Multiple markers at this line
- parameter names (without types) in function declaration [enabled by
default]
- Unused declaration of function 'test_function'
I think the way I am calling my function is not right. Could somebody please help me. Thnak you in advance.
Disclaimer: nested functions are non-standard C and I only know (of) the GNU extension for this. As such anything I claim here may well be untrue in another implementation. My recommendation is that you just don't use them at all.
Your nested test_function is shadowing the global declaration. So the test_function you declared above main is never called, because the call inside main refers to the nested function. Hence, you get a warning.
You should declare int test_function outside of main
for example.
int test_function(int x)
and then call the function in main.
value = test_function(x)
This is what your code should look like:
#include <stdlib.h>
#include <stdio.h>
int test_function(x)
{
int value = 0;
if (x==0)
{
printf("the letters are the same");
}
return value;
}
int main(){
int x = 0;
char letter[] ={"HAAA"};
char cmpre[] = {"AHD"};
int value = 0; // unused
for(int i=0; i<4;i++)
{
if(letter[i] == cmpre[i])
{
x=0;
}
}
printf("To check if the letters are the same go to the function");
test_function(x);
return 0;
}
Note that if you dont need a return value you could make the function void.
And initialize your variables. You may search hours to find such a error

conflicting types for 'outchar'

I am a newbie to C programming. I'm learning by reading the chapters and doing the examples from the book "Teach Yourself C" by Herbert Schildt. I'm trying to run this program in Dev C:
#include <stdio.h>
#include <stdlib.h>
main()
{
outchar('A');
outchar('B');
outchar('C');
}
outchar(char ch)
{
printf("%c", ch);
}
but I get this error when I compile it:
20 1 C:\Dev-Cpp\main.c [Error] conflicting types for 'outchar'
21 1 C:\Dev-Cpp\main.c [Note] an argument type that has a default
promotion can't match an empty parameter name list declaration
15 2 C:\Dev-Cpp\main.c [Note] previous implicit declaration of 'outchar' was here
Please help me with this!
It's because you haven't declared outchar before you use it. That means that the compiler will assume it's a function returning an int and taking an undefined number of undefined arguments.
You need to add a prototype pf the function before you use it:
void outchar(char); /* Prototype (declaration) of a function to be called */
int main(void)
{
...
}
void outchar(char ch)
{
...
}
Note the declaration of the main function differs from your code as well. It's actually a part of the official C specification, it must return an int and must take either a void argument or an int and a char** argument.
In C, the order that you define things often matters. Either move the definition of outchar to the top, or provide a prototype at the top, like this:
#include <stdio.h>
#include <stdlib.h>
void outchar(char ch);
int main()
{
outchar('A');
outchar('B');
outchar('C');
return 0;
}
void outchar(char ch)
{
printf("%c", ch);
}
Also, you should be specifying the return type of every function. I added that for you.

Declare a void function in C

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).

Resources