Program file name - armstrong3.c.
#include <stdio.h>
#include <math.h>
int main(void) {
int i, sum, num, rem,x;
x=pow(2,5);
printf("%d\n", x);
printf("List of 3 digit armstrong numbers \n");
for (i=100; i<=999; i++) {
num=i;
sum=0;
while (num>0) {
rem=num%10;
sum=sum+pow(rem,3);
num/=10;
}
if (i==sum)
printf("%d\n", i);
}
return 0;
}
This simple program finds 3 digit armstrong numbers. To calculate the cube I am using pow() of math.h. It didn't work initially and gave the famous error during compilation:
armstrong3.c:(.text+0x91): undefined reference to `pow' collect2:
error: ld returned 1 exit status.
Then I compiled it with gcc armstrong.c -lm, and it worked fine.
Then I used another pow() function in the second line of the main() function and commented out the earlier pow() function which I was using to calculate the cube. Strangely, the program compiled fine with gcc armstrong3.c.
The program posted by me gets compiles fine using gcc armstrong.c -lm.
The following scenario is my current issue:
With the second pow() commented out it gcc armstrong.c compiles with no warnings and errors. No -lm flag required.
If I uncomment the second pow() function in the program, it does not compile and gives the above mentioned error. And with -lm it works fine.
Why is there this unusual behavior with the same function in two places inside the same program?
Compiler: gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04).
Then I used another pow() function in the second line of the main() function and commented out the earlier pow() function which I was using to calculate the cube. Strangely, the program compiled fine with gcc armstrong3.c.
pow is an intrinsic function. When you specify all its arguments as compile time constants, as in pow(2, 5), the compiler replaces the call with its value.
That only happens for integer arguments. Because when you pass floating point arguments the result of pow depends on the current floating point rounding mode, which is not known at compile time.
This behavior is caused by inlining the pow function result in case of constant expressions in its call.
Related
I'm new to coding in C so im sure this is a basic question. in my mind, this code should read an input, run the rcall() which does nothing, and output the same value. This works perfectly with int() values, but as soon as I switch to double, the output doesn't change from -6158. How do fix this logic error?
double input, output, rcall(x);
int main(void){
scanf("%lf", &input); /*read the input*/
output=rcall( input); /*call the function*/
printf("%lf", output); /*print the output*/
}
double rcall(x){ /*this function does nothing*/
return x;
}
The problem here is that you are using a 17 year old compiler, or have your current compiler incorrectly configured to compile the code as if it was older than 17 years.
The declaration double rcall(x); is nonsense in modern C.
But ancient C allowed sloppy declarations where not all types were specified, or even allowed you to call functions that had no declaration. The compiler would then always "helpfully" assume that those types that weren't explicitly specified are all int. If it turned out that they actually weren't, your program would then crash and burn.
This sheer stupid system was removed from the C language in the year 1999, with the "C99" standard. In modern C, your declaration should be
double rcall (double x);
and the definition should be
double rcall (double x)
{
return x;
}
In case you are using GCC, you can configure it to correct code according to modern standard C by adding the options gcc -std=c11 -pedantic-errors. Then you would have gotten a compiler error for the original code.
Declare x as a double type
double rcall(double x)
I've got a function that takes a matrix of velocities for a bunch of particles and tries to calculate the total kinetic energy of the particles.
It doesn't give me the right value. In order to debug, I added a few printf("value: %e \n", energy) in the function.
And now, the return value depends on how many of these printfs I leave uncommented.
double GetKineticEnergy(int dim, int nParticles, double vel[nParticles][dim], double mass)
{
int i,j;
double sum;
double energy = 0;
for(i=0;i<nParticles;i++) {
sum = 0;
for(j=0;j<dim;j++) {
sum += vel[i][j]*vel[i][j];
}
energy += sum*mass/2;
// printf("energy: %e \n", energy);
}
// printf("total: %e \n", energy);
return(energy);
}
and right after returning to the caller I print the returned value. I get 18.0, 19.0, 21.0, or 24.0, depending on which combination of the printfs I uncomment.
What am I doing wrong?
Update:
In trying to troubleshoot this, I've commented out pretty much everything. The function is reduced to
{
double energy = 123;
return(energy);
}
and the main program is
int main() {
double a;
double vel[5][5];
a = GetKineticEnergy(1, 1, vel, 1);
printf("value: %e \n", a);
}
and I get
value: 0.000000e+00
as output.
Update:
The problem goes away if I hardcode the second dimension of the 2D array double vel[][3]. For the time being, this seems like a useful fix, but I cringe at that type of hardcoding.
It can happen if GetKineticEnergy function is in a different file and prototype is not available. Consider declaring its prototype in main or include required header file.
You have invoked undefined behaviour.
When you are faced with seemingly inexplicable behaviour from a C program, it is typically the result of undefined behaviour. Here are a few potential problems that you should look into:
Compiler warnings
Compilers usually omit many important warning messages by default, and you have to enable those yourself. Compiling with optimizations enabled can also activate some additional warning messages due to the added code analysis. If you're using GCC, you should at a minimum use something like gcc -ansi -pedantic -W -Wall -O2.
Function prototypes
Have you provided correct function declarations (with prototypes) for all the functions in your code? Without a correct declaration of GetKineticEnergy(), the compiler will pass the last argument as int and assume that the return type is int.
Did you #include <stdio.h>? printf() is a variadic function. Variadic functions usually require different calling conventions than normal functions. Calling a variadic function without the correct prototype causes undefined behaviour.
Buffer overflow
Did you allocate enough memory, or specify a large enough size, for the array passed to the function? Are you passing the correct dimensions? Accessing elements beyond the limits of a buffer can cause perplexing results, especially with optimizations enabled.
I am using Code Block with GNU GCC Compiler. And I am trying this code
int number,temp;
printf("Enter a number :");
scanf("%d",&number);
temp = sqrt(number);
printf("\n%d",sqrt(number)); //print 987388755 -- > wrong result
printf("\n%d",temp); //print 3 -- > write result
return 0;
and in this code there are a result for input value 10 is
987388755
3
what is wrong in this code?
sqrt returns a double:
double sqrt(double x);
You need:
printf("\n%g",sqrt(number));
Using incorrect format specifier in printf() invokes Undefined Behaviour. sqrt() returns double but you use %d.
Change:
printf("\n%d",sqrt(number));
to:
printf("\n%g",sqrt(number));
Note that sqrt() returns a double, not an int - your compiler should be warning you about this, so long as you have warnings enabled. e.g. gcc -Wall ... (and if you don't have warnings enabled, then it's time to start making a habit of it).
when i execute the below code, the compiler returns the message "(.text+0x31): undefined reference to 'sqrt'". but if i take away the q* the compiler correctly gives me 8.000000
i'm trying to get the program to multiply the INCREMENT by 1 (and eventually 2 and 3 when i write the loop in).
how come the below doesn't work?
#include <stdio.h>
#include <math.h>
#define INCREMENT 64
int main ()
{
int q = 1;
printf("%f", sqrt(q*INCREMENT));
return 0;
}
You probably need to link to the math library. (though I thought visual C++ does this automatically...)
The reason why it works without the q is because the compiler is optimizing out the sqrt since it's a constant.
The code is correct c code. I tested it under vs 2010 and it returned the value 8. However it is not correct c++ code. sqrt becomes ambigueous when the argument is an integer. Is it possible that your source file has a .cpp extension, instead of a .c extension?
Say you have a C code like this:
#include <stdio.h>
int main(){
printf("Hello, world!\n");
printf("%d\n", f());
}
int f(){
}
It compiles fine with gcc, and the output (on my system) is:
Hello, world!
14
But.. but.. how is that possible? I thought that C won't let you compile something like that because f() doesn't have a return statement returning an integer. Why is that allowed? Is it a C feature or compiler omission, and where did 14 come from?
The return value in this case, depending on the exact platform, will likely be whatever random value happened to be left in the return register (e.g. EAX on x86) at the assembly level. Not explicitly returning a value is allowed, but gives an undefined value.
In this case, the 14 is the return value from printf.
compile with -Wall to enable more sanity checking in the compiler.
gcc -Wall /tmp/a.c
/tmp/a.c: In function ‘main’:
/tmp/a.c:5: warning: implicit declaration of function ‘f’
/tmp/a.c:6: warning: control reaches end of non-void function
/tmp/a.c: In function ‘f’:
/tmp/a.c:10: warning: control reaches end of non-void function
Note how it flags up the missing return statements - as "control reaches end of non-void function"?
Always compile using -Wall or similar - you will save yourself heartache later on.
I can recall several occasions when this exact issue has caused hours or days of debugging to fix - it sorta works until it doesn't one day.
14 is exactly the return value of the first printf, also. Probably, the compiler optimized out the call to f() and then we're left with 14 on EAX.
Try compiling your code with different optimization levels (-O0, -O1, -O2, -O3, -Os) and see if the output changes.
18 is the return value of the first print statement. (the number of characters printed)
This value is stored in stack memory.
In second printf function the stack value is 'returned' by function f. But f just left the value that printf created in that slot on the stack.
for example, in this code:
#include <stdio.h>
int main(){
printf("Hello, world!1234\n");
printf("%d\n", f());
}
int f(){
}
Which compiles fine with gcc, and the output (on my system) is:
Hello, world!
18
for details of printf() returning value mail me.
You probably have the warning level of your compiler set very low. So it is allowed, even if the result is undefined.
The default return value from a
function is int. In other words,
unless explicitly specified the
default return value by compiler would
be integer value from function.
So, the ommiting of return statement is allowed, but undefined value will be returned, if you try to use it.
I compile with -Werror=return-type to prevent this. GCC will give an error if you don't return from a function (unless it's void return).