Macros (created with #define ) are handled by the preprocessor, not the compiler. The preprocessor is dumb and doesn't understand what C++ is, it just does find and replace as you tell it to. No type information exists at the time that this is happening.
Everywhere you use "PI" or "ZERO", the preprocessor just replaces it with "3.14159" or "0" as if you had written that originally. The compiler then sees that and has no idea that any macros were ever there to begin with.
As for your two floats, they are identical - no amount of zeroes after the decimal place will have any effect.
Thank you LB. Most is clear. One question remains though: does it mean that some function can take some undefined type of variable (by #define) as input; let's say a float as a character? Doesn't the function need overload possibilities?
does it mean that some function can take some undefined type of variable
No. Types are always exist in C++. There is no such thing as an undefined type.
Using LB's example, PI is replaced by the preprocessor with 3.14159. That is implicitly a floatdouble to the compiler. Likewise, the compiler substitutes 0 for ZERO. That is implicitly an int.
Edit: Corrected float to double. Thank you Peter87.
OK AbstractionAnon
Does this mean that a function calling a variable set by "#define" has to cast that variable; in a fact converting it. Or does it automatically convert. Say PI is called as a char...
I'm not looking for troubles, i want to know ;-)
Does this mean that a function calling a variable set by "#define" has to cast that variable
I think you're missing the point. As previously explained, #define is a text substitution mechanism handled by the preprocessor. Again using LB's example, when the preprocessor sees the token PI, it removes the token PI and substitutes the token 3.14159. The compiler operates just as if you had written 3.15159 instead of PI.
Yes, i can not explain in right terms what is bothering me. Is in a fact c++ loosely typed?
1 2 3 4 5 6 7 8 9 10 11
#include <iostream>
usingnamespace std;
#define PI 3.14159
int main ()
{
int ros = 12 * PI;
cout << ros << endl;
double rox = 12 * PI;
cout << rox << endl;
return 0;
}
When compiled; is PI already 'integer-ed' to 3 in ros? And is PI a ready float to rox? (Both given the fact that, in this case 12, is a variable input.)
As added clarification:
The right-hand side of both lines,
int ros = 12 * 3.14159;
double rox = 12 * 3.14159;
both evaluate to the same value. A floating point numerical value literal is a double by default as Peter87 noted above. Before performing the multiplication the integer 12 will be promoted to a double due to C++'s implicit promotion of numerical types in performing arithmetic operations. Thus the result of the right-hand side is 37.69908 as a double. The assignment to the integer ros then yields 37 due to truncation of the decimal part and the assignment to rox yields 37.69908
Think of macro expansion this way: You have written your code in a text editor, but before sending the text file to the compiler you use your editor's search and replace function to replace PI by 3.14159 and then delete the line #define PI 3.14159 . The resulting text file is what is sent to the compiler. Consequently, the compiler has no idea what the symbol PI is so int ros = 12 * (int)PI makes no sense.
To illustrate further the preprocessor's search and replace of define macros, suppose you had a line in the code double smallPI=3.14;
By the time the code is fed to the compiler that line will become: double small3.14159= 3.14;
This will not compile since small3.14159 is not a legal identifier name because of the decimal point. This type of unexpected macro expansion can be insidious.
There is a notorious problem in Windows due to a Microsoft macro in windows.h called max defined as follows:
#define max(a, b) (((a) > (b)) ? (a) : (b))
This macro conflicts with the same identifier as used in the standard library. There are workarounds, but if you are not already aware of the problem it can lead to strange cryptic error messages. Prefer const variables over define macros.
@peterbaaj yes the compiler might not be able to compile for ambigious call.
@AbstractionAnon A class (user defined type) can be undefined but declared. You might have compiler errors when forward declaring but calling a method in the header because the compiler did not read yet the cpp. (the important one that creates the obj )
@AbstractionAnon A class (user defined type) can be undefined but declared. You might have compiler errors when forward declaring but calling a method in the header because the compiler did not read yet the cpp. (the important one that creates the obj )
That's true, but what does that have to do with what I posted, or with the difference between #define and const variables?
even using auto the compiler might no able to find an appropriate type , it is rare but I ve seen it.
I don't believe you. If the compiler cannot deduce a type for auto it will result in a compilation error. Please show an example of what you are talking about.