8

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;
}
John Kugelman
  • 349,597
  • 67
  • 533
  • 578

4 Answers4

13

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)

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Declarataions of the methods before main? Or declarations of the variables before main? –  Sep 21 '15 at 20:14
  • @John I am talking specifically of declarations of the *functions* that have not already been declared before they get used. – juanchopanza Sep 21 '15 at 20:15
  • Thanks for the response, @juanchopanza! One more question: in C do i have to declare a function before I call it inside the other function? –  Sep 21 '15 at 20:46
  • @John Since c99, you do. Before that, you could use the implicit declaration, but then you must make sure the definition is compatible with the implicit declaration. Calling a function with the wrong types of parameters could lead to undefined behaviour. – juanchopanza Sep 21 '15 at 20:56
6

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.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

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.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • 1
    "*Functions must at least be declared before they are called* -- Yes. *"if possible, they should be defined before they are called"* -- Why? – Keith Thompson Sep 21 '15 at 21:09
  • Thank you! I've tried your way and now it's saying: `expected expression before 'void'` in lines `C = enterChar();` and `N = enterNum();`. Could you explain why this happens? –  Sep 21 '15 at 21:14
  • @KeithThompson: minimize potential for mayhem. Since the declaration and the definition are one and the same, you avoid problems where you update one and forget to update the other. But, this only applies where the definitions are in the same file as the caller. – John Bode Sep 21 '15 at 21:14
  • @John: when you say "my way", do you mean you moved the definitions of the functions before `main`? – John Bode Sep 21 '15 at 21:18
  • I've declared all of the methods before main() and getting those errors. –  Sep 21 '15 at 21:19
  • @John: that's...interesting. You get the error on the lines that *call* the functions? Are you trying to pass `void` as an argument in the function call? – John Bode Sep 21 '15 at 21:20
  • @JohnBode, it says `variable 'N' set but not used ` but I used it inside `switch` –  Sep 21 '15 at 21:21
  • @John: This is sounding like you have a mismatched `{` or `}` in your code. Make sure they all pair up. – John Bode Sep 21 '15 at 21:22
  • Yes, I have the word `void` both here: `C = enterChar(void);` and in the method `char enterChar(void)`, @JohnBode –  Sep 21 '15 at 21:23
  • @JohnBode: If you separate the declarations and definitions, you should get a compile-time error if they're inconsistent. Certainly defining each function before any calls is a valid approach, but it's not the only one (and it doesn't work in the presence of recursion). – Keith Thompson Sep 21 '15 at 21:27
  • @John: A function call with no arguments uses empty parentheses: `C = enterChar();`. A function declaration or definition with no parameters uses `(void)`. (Using empty parentheses in all 3 cases would have made more sense, but that wasn't feasible for historical reasons.) – Keith Thompson Sep 21 '15 at 21:28
  • @John: You don't pass `void` in the function call; you only use it in the function declaration/definition. – John Bode Sep 21 '15 at 22:06
0

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;
}
Weather Vane
  • 33,872
  • 7
  • 36
  • 56