Functions' order in C - c

Why does my code work ? I am calling the function generateNumber before declaring it, and I haven't set a prototype at the beginning of the file, so normally it shouldn't work, should it ?
Here is my code :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, const char * argv[]) {
int max = 100;
int min = 1;
int mysteryNumber = generateNumber(min, max);
int enteredNumber = min-1;
do{
printf("Enter a number !\n");
scanf("%d", &enteredNumber);
if (enteredNumber > mysteryNumber) {
printf("It's less !");
}else if(enteredNumber < mysteryNumber){
printf("It's more !");
}
}while (enteredNumber != mysteryNumber);
printf("Congratulations, the mystery number was %d \n", mysteryNumber);
return 0;
}
int generateNumber(int min, int max){
srand(time(NULL));
return (rand() % (max - min + 1)) + min;
}
Thanks by advance !

Surprisingly, this is one of the rare cases when it actually should work with old compilers - specifically, with compilers prior to C99. Still, you shouldn't do it: implicit int has been removed in C99, because it makes code fragile.
When a function lacks prototype, older C compilers used to assume that all its arguments match the types of expressions that you pass, and that their return type is int. Your function happens to match this description: you pass two integers, and treat the return value as an int.

You are right it shouldn't work. My gcc (6.1.0) produces:
test.c: In function ‘main’:
test.c:9:25: warning: implicit declaration of function ‘generateNumber’ [-Wimplicit-function-declaration]
int mysteryNumber = generateNumber(min, max);
^~~~~~~~~~~~~~
It "works" because most compilers are permissive of this by providing an implicit function declaration. However, it's not valid in modern C.
Before C99 removed this implicit function declaration from the standard, it was allowed. But it's not valid anymore since C99.
If your compiler doesn't provide warnings for this, try to increase the warning levels.

Related

"error: conflicting types" when trying to return a character-array reference [duplicate]

This question already has an answer here:
note: previous implicit declaration of ‘point_forward’ was here
(1 answer)
Closed 1 year ago.
In an effort to learn C and string operations, I'm making a small program that simply generates random IP addresses as strings and outputs it. From what I've gathered from various tutorials as well as examples here on stackoverflow, the below would be one way of doing so, but returning the character array reference is what stumps me, as it doesn't compile:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *testip = randip();
printf("%s", testip);
free(testip);
return 0;
}
// get rand IP
char* randip()
{
char *ip = malloc(16);
int a = randint(1,254);
int b = randint(0,254);
int c = randint(0,254);
int d = randint(0,254);
sprintf(ip, "%d.%d.%d.%d", a, b, c, d);
printf("D> randip generated %s", ip);
return ip;
}
// generate rand int
int randint(unsigned int min, unsigned int max)
{
double scaled = (double)rand()/RAND_MAX;
return (max - min +1)*scaled + min;
}
gcc output:
test.c: In function ‘main’:
test.c:8:18: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c: At top level:
test.c:17:7: error: conflicting types for ‘randip’
test.c:8:18: note: previous implicit declaration of ‘randip’ was here
I am unable to see which types are incompatible? Did I accidentally return, call, or miscast a type I didn't intend for?
Note: Yes, I know my randomness isn't very random, and there are probably better way of handling that part, but that's outside of the scope of this question.
You need the function prototype before it is called.
If the function does not take parameters declare it as char* randip(void)
Use the correct main signature. In this case int main(void)
int randint(unsigned int min, unsigned int max);
char* randip(void);
int main(void)
{
/* ...*/
}
char* randip(void)
{
/* ...*/
}
// generate rand int
int randint(unsigned int min, unsigned int max)
{
/* ...*/
}

Can the place of function declaration in C affect the branch prediction?

Here's a code:
#include <stdio.h>
/* declaration */
int square (int num);
int main() {
int x, result;
x = 5;
result = square(x);
printf("%d squared is %d\n", x, result);
return 0;
}
/* definition */
int square (int num) {
int y;
y = num * num;
return(y);
}
And when I change it like this:
#include <stdio.h>
/* declaration */
int main() {
int x, result;
x = 5;
result = square(x);
printf("%d squared is %d\n", x, result);
return 0;
}
/* definition */
int square (int num);
int square (int num) {
int y;
y = num * num;
return(y);
}
I get the warning:
Implicit declaration of the function 'square'
Does this warning has any relation with the branch prediction things? Does the former code improves branch prediction and hence the performance of the code (as the function call branches/diverts the execution from the normal execution of the code!?)
No, it has nothing to do with branch prediction.
The language requires that a declaration of a function appear before the function is called. The compiler needs to see the declaration in order to generate code for the function call that is even correct, let alone performant: to know what types are expected as parameters, what type is returned, how the parameters should be laid out in the stack and registers, and so on. And by the one-pass design of the C language, this means the declaration has to appear before the function call. It's true that the necessary information is further down in the source file, but that's too late - the compiler isn't designed to "peek ahead" for it.
In modern C, the absence of the declaration makes the program invalid, and the compiler must issue a diagnostic. Previous versions of the C language allowed such a program to compile, using an "implicit declaration" which was essentially a standard set of rules to guess what types were expected and returned, and how they should be passed. Some compilers, such as gcc, proceed under these earlier rules when they find a missing declaration, and only give a warning instead of an error (which complies with the requirement for a diagnostic). But as the programmer, you really should consider it an error, since there's a good chance that the "guessed" implicit declaration will be wrong for your function, in which case the compiled program may fail in unpredictable ways at runtime.

C language - calling functions without function prototype

I found here that function prototype is necessary before function call if the function is below function calling.
I checked this case in gcc compiler and it compile code without function prototype.
Example:
#include <stdio.h>
//int sum (int, int); -- it runs with this commented line
int main (void)
{
int total;
total = sum (2, 3);
printf ("Total is %d\n", total);
return 0;
}
int sum (int a, int b)
{
return a + b;
}
Could explain somebody this issue?
When you don't provide a function prototype before it is called, the compiler assumes that the function is defined somewhere which will be linked against its definition during the linking phase. The default return type is assumed to be int and nothing is assumed about the function parameter. This is called implicit declaration. This means that the assumed function signature here is
int sum();
Here, the empty parameter list means the function sum takes a fixed but unknown number of arguments all of which are of unknown types. It is different from the function declaration
int sum(void);
However, in C++, the above two declarations are exactly the same. If your function has a return type other than int, then the assumed function signature won't match and this will result in compile error. In fact, it's an error in C99 and C11. You should always provide function prototype before it is called.
It says on this page that: " You don't have to declare the function first, but if you don't, the C compiler will assume the function returns an int (even if the real function, defined later, doesn't)."
It is confirmed here.
As for arguments: "and nothing is assumed about its arguments."
I changed your code to #include
/* int sum (int, int); -- it runs with this commented line */
int
main (void)
{
int total;
total = sum (2, 3);
printf ("Total is %d\n", total);
return 0;
}
int
sum (int a, int b)
{
return a + b;
}
Then compile with:
gcc --std=c90 -ansi -pedantic node.c
Also i try with some standard but may be it's related to gcc version and C standard.

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

About Use Of Storage Classes in C

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

Resources