Inconsistency using printf - c

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

Related

is there a different syntax for functions with double in c?

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)

Output not match the code in c (double variable)

I am new with c and I'm trying to use doubles variable. Unfortunately, the compiler (Code::Blocks) seems to ignore absolutely what i'm writing.
#include<stdio.h>
int main()
{
double x=1.03;
printf("x: %lf",x);
return 0;
}
and the output is:
x: 0.000000
what is the problem?
Use %f instead of %lf. Doubles only need %f; see the "specifiers" table here.
If printf is looking for a larger value than you are providing, what prints out will be affected by what happens to be in memory near the x argument that you provided. In this case, I'm guessing that's 0.
Edit: Thanks to #Olaf for pointing out that the specification says %lf should work just fine. Apparently the OP's compiler or compiler version is nonstandard. Alternatively, perhaps the project settings are selecting nonstandard compiler behaviour. (I suppose the compiler or library implementation of printf could be buggy, as well.)

Unusual behavior of pow() in C during compilation

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.

Returned value depends on how many printf are in the function

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.

Behaviour of printf when printing a %d without supplying variable name

I've just encountered a weird problem, I'm trying to printf an integer variable, but I forgot to specify the variable name, i.e.
printf("%d");
instead of
printf("%d", integerName);
Surprisingly the program compiles, there is output and it is not random. In fact, it happens to be the very integer I wanted to print in the first place, which happens to be m-1.
The errorneous printf statement will consistently output m-1 for as long as the program keeps running... In other words, it's behaving exactly as if the statement reads
printf("%d", m-1);
Anybody knows the reason behind this behaviour? I'm using g++ without any command line options.
#include <iostream>
#define maxN 100
#define ON 1
#define OFF 0
using namespace std;
void clearArray(int* array, int n);
int fillArray(int* array, int m, int n);
int main()
{
int n = -1, i, m;
int array[maxN];
int found;
scanf("%d", &n);
while(n!=0)
{
found=0;
m = 1;
while(found!=1)
{
if(m != 2 && m != 3 && m != 4 && m != 6 && m != 12)
{
clearArray(array, n);
if(fillArray(array, m, n) == 0)
{
found = 1;
}
}
m++;
}
printf("%d\n");
scanf("%d", &n);
}
return 0;
}
void clearArray(int* array, int n)
{
for(int i = 1; i <= n; i++)
array[i] = ON;
}
int fillArray(int* array, int m, int n)
{
int i = 1, j, offCounter = 0, incrementCounter;
while(offCounter != n)
{
if(*(array+i)==ON)
{
*(array+i) = OFF;
offCounter++;
}
else
{
j = 0;
while((*array+i+j)==OFF)
{
j++;
}
*(array+i+j) = OFF;
offCounter++;
}
if(*(array+13) == OFF && offCounter != n) return 1;
if(offCounter ==n) break;
incrementCounter = 0;
while(incrementCounter != m)
{
i++;
if(i > n) i = 1;
if(*(array+i) == ON) incrementCounter++;
}
}
return 0;
}
You say that "surprisingly the program compiles". Actually, it is not surprising at all. C & C++ allow for functions to have variable argument lists. The definition for printf is something like this:
int printf(char*, ...);
The "..." signifies that there are zero or more optional arguments to the function. In fact, one of the main reasons C has optional arguments is to support the printf & scanf family of functions.
C has no special knowledge of the printf function. In your example:
printf("%d");
The compiler doesn't analyse the format string and determine that an integer argument is missing. This is perfectly legal C code. The fact that you are missing an argument is a semantic issue that only appears at runtime. The printf function will assume that you have supplied the argument and go looking for it on the stack. It will pick up whatever happens to be on there. It just happens that in your special case it is printing the right thing, but this is an exception. In general you will get garbage data. This behaviour will vary from compiler to compiler and will also change depending on what compile options you use; if you switch on compiler optimisation you will likely get different results.
As pointed out in one of the comments to my answer, some compilers have "lint" like capabilities that can actually detect erroneous printf/scanf calls. This involves the compiler parsing the format string and determining the number of extra arguments expected. This is very special compiler behaviour and will not detect errors in the general case. i.e. if you write your own "printf_better" function which has the same signature as printf, the compiler will not detect if any arguments are missing.
What happens looks like this.
printf("%d", m);
On most systems the address of the string will get pushed on the stack, and then 'm' as an integer (assuming it's an int/short/char). There is no warning because printf is basically declared as 'int printf(const char *, ...);' - the ... meaning 'anything goes'.
So since 'anything goes' some odd things happen when you put variables there. Any integral type smaller than an int goes as an int - things like that. Sending nothing at all is ok as well.
In the printf implementation (or at least a 'simple' implementation) you will find usage of va_list and va_arg (names sometime differ slightly based on conformance). These are what an implementation uses to walk around the '...' part of the argument list. Problem here is that there is NO type checking. Since there is no type checking, printf will pull random data off the execution stack when it looks at the format string ("%d") and thinks there is supposed to be an 'int' next.
Random shot in the dark would say that the function call you made just before printf possibly passed 'm-1' as it's second parm? That's one of many possibilities - but it would be interesting if this happened to be the case. :)
Good luck.
By the way - most modern compilers (GCC I believe?) have warnings that can be enabled to detect this problem. Lint does as well I believe. Unfortunately I think with VC you need to use the /analyze flag instead of getting for free.
It got an int off the stack.
http://en.wikipedia.org/wiki/X86_calling_conventions
You're peering into the stack. Change the optimizer values, and this may change. Change the order of the declarations your variables (particularly) m. Make m a register variable. Make m a global variable.
You'll see some variations in what happens.
This is similar to the famous buffer overrun hacks that you get when you do simplistic I/O.
While I would highly doubt this would result in a memory violation, the integer you get is undefined garbage.
You found one behavior. It could have been any other behavior, including an invalid memory access.

Resources