Printing control with C - c

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?

Related

atof("0") returns 2 in float variable

I write c embedded on STM32F437VI. At some point, I need to parse some strings that contain numbers, as float numbers. I use atof and it works always with the correct result, except for this one weird case. If the string is 0 or 0.0 it gives 2.
I have included stdlib.h and even tried (float)atof() to typecast, but for some weird reason, the float variable has always the value 2 from the atof("0") operation and the double value has the correct 0.
Why is this happening? Thank you all in advance.
#include "stdio.h"
#include "stdlib.h"
int main(void)
{
char test[] = "0";
float val1;
double val2;
val1 = atof(test);
val2 = atof(test);
return 0;
}
I expect the obvious result of 0 to the float variable as well, but it keeps getting the fixed 2 value.
UPDATE:
This code section is part of a much bigger project and there is no point in elaborating on the project. I have custom Makefile with LDFLAG option
"-mfloat-abi=hard -mfpu=fpv4-sp-d16 -u _printf_float".
Could this affect this issue?
As the MCV example is concerned, in main.c I have the above code section and I got the results mentioned.
Can anybody think of any reason atof() behaves in this way?
Of course I have used online c compiler as well with the exact same code and the result is of course 0. I guess if something was very very wrong with the stdlib library, then atof() would not work for all the other cases as well. But it fails only for "0" and only with the result 2 assigned to the float variable.
I watch the variables realtime with Ozone debugger software.
Could the reason be the floating point implementation on STM32F4 mcu used? A missing parameter in the custom Makefile or something like that?
First, your question lacks a Minimal, Complete, and Verifiable example.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char test[] = "0";
float val1;
double val2;
val1 = atof(test);
printf("%f\n", val1);
val2 = atof(test);
printf("%f\n", val2);
}
Output:
0.000000
0.000000
<°)))<()
Or your standard library implementation is fubar.
It looks like the cause of your problem is in the updated question text:
UPDATE: This code section is part of a much bigger project and there is no point in elaborating on the project. I have custom Makefile with LDFLAG option
"-mfloat-abi=hard -mfpu=fpv4-sp-d16 -u _printf_float".
Assuming these options are changes vs the defaults, what you're doing is telling the compiler to generate code for a different ABI from your toolchain's library ecosystem. The code generated for main expects the result of atof in a floating point register, but atof is using the standard ABI, which passes floating point arguments and return values in general-purpose registers. Thus, main is just reading whatever junk happens to be left in the floating point registers used for return values.
See if your problem goes away if you remove -mfloat-abi=hard. If so, you've probably found your problem. You need to either build a toolchain and libraries for the hardfloat ABI, or stick with the default non-hardfloat calling convention.

'system' was not declared in this scope error

So i dont get this error in other programs but i did get it in this.
This program is an example where i dont get the error.
#include<stdio.h>
int main() {
system("pause");
} // end main
but in this program below i get the error
#include <stdio.h>
//#include <stdlib.h>
// Takes the number from function1, calculates the result and returns recursively.
int topla (int n) {
if(n == 1)
return 3;
else
return topla(n-1) + topla(n-1) + topla(n-1);
}
// Takes a number from main and calls function topla to find out what is 3 to the
// power of n
int function1(int n) {
return topla(n);
}
int main() {
int n; // We us this to calculate 3 to the power of n
printf("Enter a number n to find what 3 to the power n is: ");
scanf("%d", &n);
function1(n);
system("pause");
} // end main
Just include stdlib.h, but don't use system("pause") as it's not standard and will not work on every system, just a simple getchar() (or a loop involving getchar() since you've used scanf()) should do the trick.
And normally system("pause") is found in windows command line programs because windows command prompt closes when the program exits, so maybe running the program from the command prompt directly would help, or using an IDE that fixes this like geany.
Finally always check the return value if scanf() instead of assuming that it worked.
Note: This code
return topla(n - 1) + topla(n - 1) + topla(n - 1)
you can write as
return 3 * topla(n - 1);
instead of calling topla() recursively 3 times.
And you don't really need the else because the function returns unless the n != 1 so even without the else the recursion will stop when n == 1.
The system function is declared in the standard header <stdlib.h>. If your program calls system(), you must have
#include <stdlib.h>
at or near the top of your source file.
But part of your question is: why didn't the compiler complain when you omitted the #include directive?
The 1990 C standard (sometimes called "ANSI C") permits calls to functions that have not been explicitly declared. If you write, for example:
system("pause");
with no visible declaration for the system function, it would be assumed that system is declared with a return type of int and parameters matching the arguments in the call -- in this case, a single argument of type char*. That happens to be consistent with the actual declaration of system, so with a C90 compiler, you can get away with omitting the #include directive. And some C compilers that support the more current 1999 and 2011 standards (which don't permit implicit declarations) still permit the old form, perhaps with a warning, for the sake of backward compatibility.
Even given a C90 compiler, there is no advantage to depending on the now obsolete "implicit int" rule. Just add the #include <stdlib.h>. More generally, for any library function you call, read its documentation and #include the header that declares it.
As for why you got an error with one of your programs and not another, I don't have an explanation for that. Perhaps you invoked your compiler with different settings. In any case, it doesn't really matter -- though you might look into how to configure your compiler so it always warns about things like this, so you can avoid this kind of error.
Here you need to know about two things.
Firstly, your code works absolutely fine and the program really finds the value of 3^n. So do not worry about that.
Coming to the system() part,
In order to use the system(); function, you need to include the stdlib.h header file, as the function is declared in that header.
So it is a good practice to include the header (rather than commenting it).
Now, the pause keyword is used in windows, to stop the console from closing after the completion of the program and it is only for windows.
Note that, system("pause"); is also not a standard, and it does not work on other machines, namely linux as, with the system command, you are directly interacting with the command line. In this regard, the commands for each operating system are specific, and they cannot be used for other OS.
so it is better that you use getchar(); , a C standard library function, to hold the console window.

How does a forward declaration work?

I understand declaring factorial before main. But how can main calculate the answer when the factorial formula comes after it?
#include <stdio.h>
long long factorial(int);
int main()
{
int n;
long long f;
printf("Enter a number and I will return you its factorial:\n");
scanf_s("%d", &n);
if (n < 0)
printf("No negative numbers allowed!\n"); //prevent negative numbers
else
{
f = factorial(n);
printf("The factorial of %d is %ld\n", n, f);
}
return 0;
}
long long factorial(int n)
{
if (n == 0)
return 1;
else
return (n * factorial(n - 1));
}
But how can main calculate the answer when the factorial formula comes after it?
First thing — main does not calculate the answer; it's your factorial function which does it for you. Also there are 3 steps which I feel you need to know about when writing programs:
You write the code in a file.
You compile the file and the compiler checks for syntactical mistakes, no code calculation is happening in this phase its just mere lexical analysis.
Then linking takes place later. If you receive a linker error, it means that your code compiles fine, but that some function or library that is needed cannot be found. This occurs in what we call the linking stage and will prevent an executable from being generated. Many compilers do both the compiling and this linking stage.
Then when you actually run your code — it's then when the code's control flow goes into the factorial function when the calculation happens, i.e. at runtime. Use a Debugger to see this.
The below image is taken from Compiling, Linking and Building C/C++ Applications
From Wiki:
In computer programming, a forward declaration is a declaration of an
identifier (denoting an entity such as a type, a variable, a constant,
or a function) for which the programmer has not yet given a complete
definition....
This is particularly useful for one-pass compilers and separate
compilation. Forward declaration is used in languages that require
declaration before use; it is necessary for mutual recursion in such
languages, as it is impossible to define such functions (or data
structures) without a forward reference in one definition: one of the
functions (respectively, data structures) must be defined first. It is
also useful to allow flexible code organization, for example if one
wishes to place the main body at the top, and called functions below
it.
So basically the main function does not at all need to know how factorial works.
But how can main calculate the answer when the factorial formula comes after it?
The order in which a C program executes is only partially determined by the order in which the text appears.
For instance, look at the printf function you are using. That doesn't appear in your program at all; it is in a library which is linked to your program.
The forward declaration makes it known (from that point in the translation unit) that there is expected to exist such and such a function having a certain name, arguments and return value.
The simple answer is that your C program is processed from beginning to end before it begins to execute. So by the time main is called, the factorial function has already been seen and processed by the C compiler.
An address is assigned to the compiled factorial function, and that address is "backpatched" into the compiled main function when the program is linked.
The reason forward declarations are needed at all is that C is an old-fashioned language originally designed to allow one-pass compilation. This means that the compiler "translates as it goes": functions earlier in a translation unit are compiled and emitted before later functions are seen. To correctly compile a call to a function which appears later (or, generally, appears elsewhere, like in another translation unit), some information must be announced about that function so that it is known at that point.
It works in this manner: let's take an example to find factorial of 3
Recursion :
As factorial of 0 is 1 and factorial of 1 is also 1, so you can write like
if(n <= 1)
return 1;
Since in main function when compiler sees this f = factorial(n); function, the compiler has no idea of what it means. it doesn't know where the function being defined, but it does know the argument the function is receiving is correct, because it's a user defined function that has its definition after main function.
Hence there should be some way to tell the compiler that I am using a function with name factorial which returns long long with a single int argument; therefore you define a prototype of the function before main().
Whenever you call the function factorial the compiler cross checks with the function prototype and ensures correct function call.
A function prototype is not required if you define the function before main.
Example case where function prototyping is not required :
/*function prototyping is not required*/
long long factorial(int n)
{
//body of factorial
}
int main()
{
...
f=factorial(n);
...
}
Here, the compiler knows the definition of factorial; it knows the return type, the argument type, and the function name as well, before it is called in main.

gcc dump resolved defines

I have code like
#define ONE 1
#define TWO 2
#define SUM (ONE+TWO)
How do I dump SUM as "3", the resolved value, in gcc 4.3+?
gcc -dM -E foo.h only seems to dump it as is. How do I get the actual value like it's inserted on compilation stage?
You can't. As far as the compiler is concerned, the line printf("%d\n", SUM) before preprocessing is indistinguishable from the line printf("%d\n", 1+2). The compiler just happens to perform an optimization called constant folding, even at the default optimization level (-O0), which turns the result into a constant 3 at runtime.
There's not really a good way to see the output of these optimizations. You could use the -S option to view the generated assembly code and see what that looks like, but if your program is anything larger than a toy, that will be a lot of manual effort. You could also look at the parse tree by using one of the -fdump-tree options (see the GCC man page).
You can't "dump" SUM as 3 because SUM isn't 3 in any meaningful sense, it's just a sequence of the three tokens ONE, + and TWO. What it turns into depends on the context where it is expanded.
Macros are expanded where they appear in the source, macro replacements are just strings of tokens until then.
You can test this like this.
#include <stdio.h>
#define ONE 1
#define TWO 2
#define SUM ONE+TWO
int a = SUM;
#undef ONE
#define ONE 2
int b = SUM;
int main()
{
printf("a = %d\nb = %d\n", a, b);
return 0;
}
Here's another example:
#include <stdio.h>
#define ONE 1
#define TWO 2
#define SUM ONE+TWO
int main()
{
/* prints 6, not 2 */
printf("5 - SUM = %d\n", 5 - SUM);
return 0;
}
With this example there's no way you can justify SUM being 3.
Contrary to the other answers, there's definitely a solution to this problem, especially with gcc extensions. Parse the output of gcc -dM and generate a C file containing lines of the form __typeof__(MACRO) foo = MACRO; and go from there. Without __typeof__ you could still handle all arithmetic types fairly well by just using long double.
One way is to stop at the precompiler stage (-E) and examine that output.

how to put an array character into the equation?

i try to put 8 byte character into the equation causing a lot of error,what i'm supposed to do to make sure the equation can take the static value and produce output in the 8 bytes.
#include <math.h>
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
void voltage_measure(void);
void main(void) {
voltage_measure();
}
void voltage_measure(void) {
char Van1[8],VA;
char Vbn[8],VB;
char Vcn[8],VC;
char AC[4],ac;
char BC[4],bc;
char AB[4],ab;
double Vab1,Vab2,Vbc1,Vbc2,Vac1,Vac2;
double Vab[8],Vbc[8],Vac[8];
Van1[0]=0xF0;
Van1[1]=0x00;
Van1[2]=0x00;
Van1[3]=0x00;
VA=0x000000F0;
Vbn[0]=0x78;
Vbn[1]=0x00;
Vbn[2]=0x00;
Vbn[3]=0x00;
VB=0x78;
Vcn[0]=0x3C;
Vcn[1]=0x00;
Vcn[2]=0x00;
Vcn[3]=0x00;
VC=0x3C;
AB[0]=0xB4;
AB[1]=0x00;
ab=0xB4;
AC[0]=0x2D;
AC[1]=0x00;
ac=0x2D;
BC[0]=0x5A;
BC[1]=0x00;
bc=0x5A;
Vab1=(VB*sin(ab))*(VB*sin(ab)) ;
Vab2=(VA+(VB*cos(ab)))*(VA+(VB*cos(ab)));
Vab[4]=sqrt(Vab1+Vab2);
Vbc1=(VC*sin(bc))*(VC*sin(bc));
Vbc2=(VB+(VC*cos(bc)))*(VB+(VC*cos(bc))) ;
Vbc[4]=sqrt(Vbc1+Vbc2);
Vac1=(VC*sin(ac))*(VC*sin(ac));
Vac2=(VA+(VC*cos(ac)))*(VA+(VC*cos(ac)));
Vac[4]=sqrt(Vac1+Vac2);
}
This is what I have understood as yet,
you want to do arithmetic with double precision that has several parameters
you would like to store the parameters in char variables (maybe to save on space?)
I don't know why you try to write VA=0x000000F0; when its a char (1 byte) variable
the static value you refer are probably the constants VA etc
It might be useful to have all these working in the arithmetic at double precision
when you use the sin and sqrt kind of functions, they will work at double anyways
you do not have a main function listed here;
it would be there in your actual file (that compiles this code)
so, i am also assuming you have things like math.h included
and the math library on the compile command
that is, you do get the binary compiled without errors
maybe you can elaborate the problem you are facing a little more?
Update from comment 1.
When you say, "character with 8 byte array" -- are you trying to create a double with an 8 char array?
Update from comment 2.
If your answer is in double, you can catch it in a double variable.
A double is already 8-bytes (on most platforms).
Is there a special reason to get it into a char array or a byte array?
Update from comment 3.
The link error implies you did include a math library for the linking.
The header just gives function prototypes for compilation.
With gcc, it would be -lm on the command line.
Update from comment 4.
To convert a double to an integer value check this page,
How can I convert a floating-point value to an integer in C?
Is the trouble that plain char on your machine is signed, so numbers such as 0xF0 are treated as -16 instead of +240? Did you know that on some machines, this is what will happen?
Concerning your link error you mentioned in the comments: including math.h is not enough, you have to tell the linker to add the library as well. Try adding "-lm" in your command line.

Resources