6

I get this error:

arthur@arthur-VirtualBox:~/Desktop$ gcc -o hw -ansi hw1.c
hw1.c: In function `main':
hw1.c:27:16: warning: assignment makes pointer from integer without a cast [enabled by default]
hw1.c: At top level:
hw1.c:69:7: error: conflicting types for `randomStr'
hw1.c:27:18: note: previous implicit declaration of `randomStr' was here

While compiling this code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
        char *rndStr;
        rndStr = randomStr(FILE_SIZE);
        /* Do stuff */
        return 0;
}

/*Generate a random string*/
char* randomStr(int length)
{
        char *result;
        /*Do stuff*/
        return result;
}

If I switch the function order around it works Why?

Heisenbug
  • 38,762
  • 28
  • 132
  • 190
AturSams
  • 7,568
  • 18
  • 64
  • 98
  • 1
    -1 for including way too much extraneous code. See http://SSCCE.ORG for information about why short complete examples are helpful. – Robᵩ Nov 08 '12 at 20:28
  • 1
    you need to declare it *before* you use it. – old_timer Nov 08 '12 at 20:29
  • @KevinDTimm - hw1.c:69:7: error: conflicting types for `randomStr' is very exact perhaps if you use c often. – AturSams Nov 08 '12 at 20:53
  • 3
    @KevinDTimm You do realize 50% of your comments only serve up to spam up this question? I searched for about 2 hours, looking for the first error and found nothing. So what, you are basically saying I'm lazy for asking in SO or stupid for not finding it myself? Last I checked SO was doing fine w/o you insulting novice C programmers. I think you should spend your precious time answering questions if you want to help others. – AturSams Nov 08 '12 at 21:17

5 Answers5

10

Except in a few exceptions, an identifier in C cannot be used before it has been declared.

Here is how to declare a function outside its definition:

// Declare randomStr function
char *randomStr(int length);
ouah
  • 142,963
  • 15
  • 272
  • 331
5

The error occurs because symbols must generally be declared before they are used, not after.

A special exception to that is functions. If they are used before declaration, a particular declaration is inferred. In your case, the inferred declaration did not match the eventual definition.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
3

In C89 and earlier, if the compiler saw a function call before a corresponding declaration or definition, it assumed that the function returned int. Similarly, if you left the type specifier off of the function definition, it was assumed to return int (this is why a lot of older examples have an entry of just main() {...} instead of int main(void) {...}).

Since the call to randomStr occurs before its declaration/definition, it is assumed to return int, which is not compatible with char * (you can't assign a value of one to the other without an explicit cast), hence the error.

As of C99, implicit typing is no longer allowed.

The -ansi option causes gcc to compile as C89. To compile as C99, use -std=c99 instead.

I generally put the function definition before its first use within the same file, so my code reads from the bottom up (main is typically the last function defined in the file). That way I don't have to worry about keeping declarations and definitions straight.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • Read my post, it's unfortunate that one can't read the code from top to bottom, which is how we're used to reading text. – mercury0114 Aug 10 '23 at 21:57
2

You need to put a function declaration before any functions that use a function that isn't defined yet.

For example:

int doesFileExist(const char* str);

would go before main().

The reason for this is that the C compiler runs through your code, and every time it sees a function, it looks to see if the function has been defined yet. If it can't find that function, it gives you an error. main() uses doesFileExist(), which has not been declared by the time the compiler looks at main(). To fix this, you can make a declaration of a function at the top, as I mentioned above. This tells the compiler that, though a function has not been filled in yet, it will be filled in later and so to treat it as if the function does exist, then go connect them later once you've found the function later on (ie, somewhere after the main() function).

Your second block of code works because the compiler has definitions for those functions which you use in main() by the time it gets there. Your first block does not work because the functions neither defined nor declared that they will be defined later.

GraphicsMuncher
  • 4,583
  • 4
  • 35
  • 50
1

Just add a function prototype

#include <stdio.h>
#include <stdlib.h>

char* randomStr(int length);

int main(int argc, char** argv)
{
        char *rndStr;
        rndStr = randomStr(FILE_SIZE);
        /* Do stuff */
        return 0;
}

/*Generate a random string*/
char* randomStr(int length)
{
        char *result;
        /*Do stuff*/
        return result;
}
Draconian Times
  • 319
  • 1
  • 3
  • 12