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

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.

Related

Clarification regarding default return type at global space

While making a function atof, I splitted the entire work into two separate translational units:
m.c
#include<stdio.h>
extern fun(char[]); //return type not mentioned on purpose
int main()
{
printf("%d\n",fun("+123.980")); //%f would also display 0.000000
return 0;
}
n.c
#include<ctype.h>
float fun(char c[])
{
float val=0, pow=1;
int i;
int sign;
for(i=0;isspace(c[i]);i++); //SKIPPING WHITESPACE IF ANY
if(c[i]=='+')
sign = 1;
if(c[i]=='-')
sign =-1;
++i;
for(;c[i]!='.';i++)
val = val*10 + (c[i]-'0');
++i;
while(isdigit(c[i]))
{
val = val*10 + (c[i]-'0');
pow=pow*10;
++i;
}
return sign*val/pow;
}
The warning says that the type of function will default to int in this case since every variable/function type at global space without any return type mentioned explicitly defaults to int.
I was expecting the output to be int version of +123.980 i.e 123 only.
But instead it shows 0 (otherwise function works fine). Why?
Implicit int and implicit function declarations are removed from the C language. They are no more. The program is ill-formed. If your compiler accepts it, then you are dealing with a vendor extension — or a compiler for an outdated version of C.
Before these things were removed, the program had undefined behaviour. All editions of the standard require that all declarations of an entity in a program must be compatible, regardless of whether anything in them is implicit or not. Violations of this rule lead to undefined behaviour, with no diagnostic required.

Confused about detecting the errors of this code in c programming language?

The code given below is an exercise that our teacher gave to prepare us for exams.
We are supposed to find the errors that occur in this code and fully explain them .
#define SIZE 10
int start (void a,int k) {
const int size=10;
char array[size];
char string[SIZE];
mycheck(3,4);
array[0]=string[0]='A';
printf("%c %c\n", array[0], string[0]);
myRec(7);
}
int mycheck(int a , int b) {
if (a==0 || b==0 ) {
return 0;
}
else {
return (a*b);
}
}
int myRec(int x) {
if(x==0)
return 0;
else
printf("%d,",x);
myRec(x--);
}
I have found these errors so far:
1.int start (void a,int k)
explanation: We can't have a variable of type void, because void is an incomplete type
2.const int size=10;
explanation:we can't use variable to define size of array
(problem is when I run it in dev-c++ it doesn't show an error so I'm not sure about this)
3.mycheck(3,4);
explanation: prototype of function mycheck() is not declared, so the function mycheck is not visible to the compiler while going through start() function
4.A friend told me that there is an error in function myRec because of this statement myRec(x--);
(I don't really get why is this an error and how you can I explain it?)
5.Main() function doesn't exist.
I'm not sure about this but if i run the code (in dev-c++) without main function I get a compilation error
I'm not sure if the errors that I pointed out are 100% right or if I missed an error or if I explained them correctly.
Please correct me if any of the above is wrong!
a friend told me that there is an error in function myRec cuz of this
statement myRec(x--);
It will lead to stackoverflow. Due to post-decrement, the actual argument passed to function myRec(), never decreases and therefore the condition:
if(x==0)
return 0;
will never become true. Regarding your rest of the errors, it depends on the compiler version being used:
For example C99, you are allowed to have variable size arrays like this:
const int size=10;
char array[size];
char string[SIZE];
but pre C99, you would have to use malloc or calloc. For your functions used without prototype, most compilers would generate a warning and not error and also due to no #include<stdio.h> statement, your printf would also lead to a warning.i Again, lot of these things are compiler dependent.
1.int start (void a,int k)
explanation: We can't have a variable of type void ,because void is an
incomplete type
Correct.
2.const int size=10;
explanation:we can't use variable to define size of array (problem is
when i run it in dev-c++ it doesnt show an error?so im not sure about
this!)
This is also correct, that char array[size];, where size is not a compile-time constant, is invalid in C89. However, in C99 and newer, this is actually valid and would create a variable-length array. It is possible that your Dev-C++ IDE is using GCC with the language set to C99 or newer, or has GNU C extensions enabled to enable this feature.
3.mycheck(3,4);
explanation: prototype of function mycheck() is not declared.So the
function mycheck is not visible to the compiler while going through
start() function
Correct. This can be fixed either by declaring the function's prototype before the start() function, or just moving the whole function to the top of the file. As noted by Toby Speight in the comments, in C89, this should not actually be a compiler error, since functions are implicitly declared when they are used before any actual declaration as int (), i.e. a function returning int with any arguments, which is compatible with the declarations of mycheck and myRec. It is however bad practice to rely on this, and implicit function declaration does not work in C99 or newer.
4.a friend told me that there is an error in function myRec cuz of this statement myRec(x--);
(I don't really get why is this an error and how you can explain it?)
This function is a recursive function. This means it calls itself within itself in order to achieve a kind of looping. However, this function as it is currently written would run forever and cause an infinite loop, and since it is a recursive function, and needs a new stack frame each time it is called, it will most likely end in a stack overflow.
The function is written with this statement:
if(x==0)
return 0;
This is intended to terminate the recursion as soon as x reaches 0. However, this never happens, because of this line of code here:
myRec(x--);
In C, postfix -- and ++ operators evaluate to their original value before the addition or subtraction:
int x = 5;
int y = x--;
/* x is now 4; y is now 5 */
However, using the prefix version of these operators will evaluate to their new value after adding / subtracting 1:
int x = 5;
int y = --x;
/* x is now 4; y is now 4 */
This means that on each recursion, the value of x never actually changes and so never reaches 0.
So this line of code should actually read:
myRec(--x);
Or even just this:
myRec(x - 1);
5.Main() function doesn't exist ...again im not sure about this but if i run the code (in dev-c++) without main function i get a compilation
error
This one could either be right or wrong. If the program is meant to run on its own, then yes, there should be a main function. It's possible that the function start here should actually be int main(void) or int main(int argc, char *argv[]). It is entirely valid however to compile a C file without a main, for example when making a library or one individual compilation unit in a bigger program where main is defined in another file.
Another problem with the program is that myRec is used before it is declared, just like your point 3 where mycheck is used before it is declared.
One more problem is that the functions start and mycheck are declared to return int, yet they both do not contain a return statement which returns an int value.
Other than that, assuming that this is the entire verbatim source of the program, the header stdio.h isn't included, yet the function printf is being used. Finally, there's the issue of inconsistent indentation. This may or may not be something you are being tested for, but it is good practice to indent function bodies, and indentation should be the same number of spaces / tab characters wherever it's used, e.g.:
int myRec(int x) {
if(x==0)
return 0;
else
printf("%d,",x);
myRec(x--);
}
1) Hello friend your Recursive function myRec() will go infinite because it
call itself with post detriment value as per C99 standard it will
first call it self then decrements but when it call itself again it have
to do the same task to calling self so it will never decrements and new
stack is created and none of any stack will clear that recursion so
stack will full and you will get segmentation fault because it will go
beyond stack size.
2) printf("%d,",x); it should be printf("%d",x); and you should include #include library.
I think your another mistake is you are calling your mycheck() and you
returning multiplication of two integer but you are not catch with any
value so that process got west.So while you are returning something you
must have to catch it otherwise no need to return it.
3) In this you Program main() function missing. Program execution starts
with main() so without it your code is nothing. if you want to execute
your code by your own function then you have to do some process but
here main() should be present.or instead of start() main() should
be present.
4) you can also allocate any char buffer like this int j; char array[j=20];
your code should be like this.
#include<stdio.h>
#define SIZE 10
int mycheck(int a , int b) {
if (a==0 || b==0 ) {
return 0;
}
else {
return (a*b);
}
}
int myRec(int x) {
if(x==0)
return 0;
else
printf("%d",x);
myRec(--x);
}
void main (int argc, char** argv) {
const int size=10;
char array[size];
char string[SIZE];
int catch = mycheck(3,4);
printf("return value:: %d\n",catch);
array[0]=string[0]='A';
printf("%c %c\n", array[0], string[0]);
myRec(7);
printf("\n");
}
Enjoy.............

Passing a structure (pointer to structure?) to a function

Ok so, I'm trying to write a program which numerically evaluates integrals using Simpson's 3/8 rule. I'm having issues passing the values from Integral *newintegral to the simpson() function. I'm not massively confident in my understanding of structures and pointers, and I've been reviewing the lecture notes and checking online for information all day and I still can't understand why it's not working.
At the moment when I try to build my program it comes up with a number of errors, particularly: on line 46 "expected expression before Integral" and on most of 55-63 "invalid type of argument of '->' (have 'Integral') I don't understand why the first one is occurring because all my lecturers examples of this type of thing, when passing a structure to a function just have the syntax func(Struct_define_name individual_struct_name). I thought this is what I was doing with mind (Integral being the name of the structure type and i being the specific structure) but obviously not.
I think these two problems are connected so I included all of my code for context, however the lines which actually have errors are 46 and 55-63 as mentioned above. I've probably defined the structure wrong in the first place or something though.
(Incidentally the maths in the simpson() function doesn't actually work properly now anyway, but that's not something I'm concerned about)
Also I tried looking at other similar questions but I didn't understand what the other code was doing so I couldn't extrapolate how to fix my code from that. I know this isn't very relevant to other people but I really don't understand programming well enough to try and phrase my question in a general sense...
'#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct integral {
double result, limits[2];
int degree;
double coefficients[];
} Integral;
// Prototype of function that calculates integral using Simpson's 3/8 rule
double simpson(Integral i);
// function (?) which initialises structure
Integral *newintegral() {
Integral *i = malloc(sizeof *i);
double lim1_in, lim2_in;
int degree_input, n;
printf("Please enter the degree of the polynomial.\n");
scanf("%d", &degree_input);
i->degree = degree_input;
printf("Please enter the %d coefficients of the polynomial, starting\n"
"from the highest power term in the polynomial.\n", (i->degree+1));
for (n=i->degree+1; n>0; n=n-1) {
scanf("%lg", &i->coefficients[n-1]);
}
printf("Please enter the upper limit of the integral.\n");
scanf("%lg", &lim1_in);
i->limits[0] = lim1_in;
printf("Please enter the lower limit of the integral.\n");
scanf("%lg", &lim2_in);
i->limits[1] = lim2_in;
return i;
}
int main() {
Integral *i = newintegral();
simpson(Integral i);
return 0;
}
double simpson(Integral i) {
int n;
double term1, term2, term3, term4;
for (n=(i->degree); n>0; n=n-1) {
term1=(pow(i->limits[1],n)*(i->coefficients[n]))+term1;
term2=(pow(((((2*(i->limits[1]))+(i->limits[0])))/3),n)*(i->coefficients[n]))+term2;
term3=(pow(((((2*(i->limits[0]))+(i->limits[1])))/3),n)*(i->coefficients[n]))+term3;
term4=(pow(i->limits[0],n)*(i->coefficients[n]))+term4;
}
i->result = (((i->limits[0])-(i->limits[1]))/8)*(term1+(3*term2)+(3*term3)+term4);
printf("The integral is %lg\n", i->result);
return 0;
}'
You're currently passing a pointer to a function that takes a single Integral argument.
Your prototype, double simpson(Integral i); tells the compiler "declare a function called simpson that returns a double and takes a single Integral referenced by the identifier i inside the function.
However, in main() you say:
int main() {
//declare a pointer to an Integral and assign it to the return of 'i'
Integral *i = newintegral();
//call the function simpson with i.
//However, you are redeclaring the type of the function argument, so the compiler will complain.
simpson(Integral i);
return 0;
}
Your call, simpson(Integral i); will not work because you are redeclaring the type of the function argument. The compiler will state:
:46:13: error: expected expression before ‘Integral’
What you really need is for simpson() to take a pointer to Integral as its argument. You have actually already handled this inside the function, (using i->) but your function prototype is telling the compiler that you are passing the whole struct Integral as the function argument.
Solution:
Change your function prototype as follows:
double simpson(Integral *i); // function returning double taking single pointer to an Integral named i.
...and change main() to look like the following:
int main(void) { //In C main has two valid definitions:
//int main(void), or int main(int argc, char **argv)
Integral *i = newintegral();
simpson(i);
return 0;
}
So in conclusion, your understanding of pointers is correct, but not how you pass a pointer to a function.
**Sidenote:
Remember to always build your code with all warnings enabled. The compiler will give you very useful diagnostics that will help you quickly find solutions to problems like this. For GCC, as a minimum, use gcc -Wall myprogram.c
Two obvious problems:-
Line 46 : simpson(Integral i);
...should be just simpson(i);. Putting a type there is simply an error.
And this, later:
double simpson(Integral i)
.. tells the compiler to pass in Integral object yet you use the indirection operator i.e i->limits as though you'd been passed a pointer. The easiest fix is to make the function expect a pointer, like this:
double simpson(Integral *i)

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

For loop says expression syntax error when initializing integer in the loop

While programming I have come to an unusual error. When I initialize an integer in a loop, sometimes it says that the expression is not valid, but at times it accepts it.
This is my code which gives error:
int pow(int x,int n);
int main()
{
int x,n,result;
printf("Enter a number:\n");
scanf("%d",&x);
printf("Enter its power:\n");
scanf("%d",&n);
result=pow(x,n);
printf("Result is %d\n",result);
getch();
return 0;
}
int pow(int x,int n)
{
for(int i=1;i<n;i++) //<-- here it says that declaration syntax error
x=x*i;
return x;
}
While when i change it like this :
int pow(int x,int n)
{
int i;
for(i=1;i<n;i++)
x=x*i;
return x;
}
C89 and earlier versions only support declaration statements at the head of a block (IOW, the only thing that can appear between an opening { and a declaration is another declaration):
/* C89 and earlier */
int main(void)
{
int x; /* this is legal */
...
for (x = 0; x < 10; x++)
{
int i; /* so is this */
printf("x = %d\n", x);
int j = 2*x; /* ILLEGAL */
}
int y; /* ILLEGAL */
...
}
With C99, declaration statements can appear pretty much anywhere, including control expressions (with the caveat that something must be declared before it is used):
// C99 and later, C++
int main(void)
{
int x; // same as before
...
for (int i = 0; i < 10; i++) // supported as of C99
{
printf("i = %d\n", i);
int j = 2 * i; // supported as of C99
}
int y; // supported as of C99
}
Turbo C predates the C99 standard, so if you want to write code like in the second example, you will need to use a more up-to-date compiler.
In C, before C99, you need to declare your variables before your loop. In C++, and now in C99, you can declare them within the loop as you try here. The different results you are getting may be because you are sometimes compiling as C++, and sometimes compiling as C.
You could try to make sure you are always compiling your code as C++, or if you're using GCC or Clang, compile with the --std=c99 flag. C99 is unsupported by MSVC, so you will either need to use C++ or move the declaration outside of the loop if you're using MSVC.
It sounds like you have a C89 compiler (rather than C99 compiler).
In C89, you are only allowed to declare variables at the beginning of a function. You are simply not allowed to declare variables elsewhere in a function, including in the initialization part of a for statement. That's why the second syntax works and the first fails.
The second syntax is valid for C99 and C++ but not for C89.
What C compiler are you using?
Older versions of C prior to C99 require all variable declarations be made at the top of a code block.

Resources