I'm starting to learn C++. Here is a problem that I have:
#include <iostream>
using namespace std;
#define PI 3.14;
int main(){
double r = 5.0;
double circle;
double inp;
circle = 2 * PI * r;
cout << circle;
cin >> inp;
}
It shows error: error C2100: illegal indirection.
I've googled but found no answer. Thanks
#define PI 3.14;
The ; is wrong, delete it.
btw, your line expands to circle = 2 * 3.14; * r;
So the compiler is then complaining about the *r, which explains the error message.
Macros are (relatively) simple substitutions so, when you write:
#define PI 3.14;
circle = 2 * PI * r;
it actually ends up as:
circle = 2 * 3.14; * r;
effectively the two statements:
circle = 2 * 3.14;
* r;
That last line would be a perfectly valid expression (albeit it not a very useful one) if r were a pointer of some description. However, given it's a double, that's where you're getting the illegal indirection from.
The use of macros is something you should generally avoid nowadays except in very specific circumstances. The use of them to provide inline functions has been subsumed mostly by the inline keyword ("mostly", because the inline keyword is only a suggestion).
In addition, using it to provide constants can be better done (with the advantage of full type support and usually better debugging) with the const keyword.
In other words, your PI constant would be better written as something like:
const double PI = 3.141592653589;
Just about the only place I use the pre-processor nowadays is for conditional compilation.
As an aside, you probably meant circumference rather than circle. The former is the length around the outside of the circle, the latter isn't really a length value at all.
Related
A topic has the following code, which is required to indicate the location of the error.
#include<iostream>
#define PT 3.5;
#define S(x) PT*x*x
void main() {
int a = 1, b = 2;
std::cout << S(a + b);
}
I think ";" caused this problem ,and deleted ';' the post compilation test can get the correct results.But the teacher thinks that variables cannot be used in macro definition.
I'm not sure who is right.
I've seen a lot of answers, but what I want to know is not whether it's reasonable to write like this, but what causes the program error in the end.
Add ';' after '#define' Not particularly good, but the compilation can pass. "#define" can also allow variables to appear. So the final error reason is "* a + b"?
There's a couple of problems. Yes, the PT will expand to 3.5; and cause a syntax error. Change that to:
#define PT 3.5
The other issue is that S(a + b) will expand to PT*a + b*a + b which is clearly not what you want. As a matter of convention, macros that perform arithmetic should wrap any expandable parts in parentheses, and the entire macro should also be in parentheses:
#define S(x) ((PT)*(x)*(x))
This ensures that you don't have to worry about expanded expressions wreaking havoc due to operator precedence rules.
Regarding the comment about your teacher...
the teacher thinks that variables cannot be used in macro definition
It's possible that they are talking about the fact that x is just a placeholder for expansion. If you pass a + b and use x twice, then a + b will be evaluated twice. Imagine if you called S(++a)... You'd get PT*(++a)*(++a)
It's usually more appropriate to just write a function, and that avoids problems like the above.
double S(int x) {
return PT * x * x;
}
Or even:
template<class T>
double S(T x) {
return PT * x * x;
}
Macros are just text substitution, so you can do pretty much anything you want, as long as the result of the substitution is valid code. So the literal answer to "Can ';' be added after #define" is yes, but the result might not work.
#define calc(x) ((x) * (x));
void f() {
int g = 3;
int h = calc(g);
}
The result of the macro expansion is
int h = ((g) * (g));;
That's valid code; the second semicolon marks the end of an empty expression, just as if it had been written
int h = ((g) * (g));
;
That's bad style, of course, and it could cause problems in other contexts, so the "right" way to use that macro would be
int h = calc(g)
That way, the text that results from the macro expansion would only have one semi-colon. But that looks weird, and the macro really shouldn't have that semicolon in it.
As to using variables, again, it depends on what the result of the text substitution is.
#define calc (x) * (x)
void f() {
int x = 3;
int y = calc;
}
That's okay; the code is equivalent to
void f() {
int x = 3;
int y = (x) * (x);
}
On the other hand, this isn't okay:
void f() {
int b = 3;
int y = calc;
}
It doesn't work because there is no x there. So this macro has vary limited usefulness; there are rare situations where it might be appropriate, but, in general, it's a bad idea.
You can't put a semicolon after PT because your macro S(X) PT*x*x would get processed to 3.5;*x*x
Your S(x) macro is breaking because the semicolons breaks it into 2 statements. First is 3.5; and the second one is *x*x
hence why you get the error.
To make it work you simply need to remove the ; in your definition of PT
my solution to find area of a triangle when base and height is given(the question specifically asked to also use float typcasting):
#include <iostream>
using namespace std;
int area()
{
int b=7,h=5;
float area;
area=(float)b*h/2;
return area;//Write a expression to find Area as float using typecasting
}
correct solution:
#include<iostream>
using namespace std;
void area()
{
int b=7,h=5;
float area;
area=(float)b*h/2;
cout<<area;
}
what's wrong with my code?
By itself I would say nothing much.
When you want to calculate a floating point number, makes sure ALL you values are floating point. Eg. not 2 but 2.0f
Casting in C++ is usually done with static_cast (or one of the other cast functions). The notation you use is more "C" style type casting
I am not a big fan of using, "using namespace" specially in larger projects. In source it can be ok, NEVER do this in header files though.
I would code it like this:
float calculate_triangle_area(const int b, const int h) noexcept
{
float area = static_cast<float>(b) * static_cast<float>(h) / 2.0f;
return area;
}
std::cout << calculate_triangle_area(5,7);
Some more notes:
I always make things functions as soon as I can give it a name. This has the added benefit of making your code more "self explaining".
The "const int" this mean you promise you won't change the values of b and h in your calculations.
The noexcept is another promise, but that's a whole topic on its own ;)
In A Tour of C++ by Bjarne Stroustrup, some advice is listed at the end of each chapter. At the end of the first chapter one of them reads:
Avoid ‘‘magic constants;’’ use symbolic constants;
What are magic and symbolic constants?
somethingElse = something * 1440; // a magic constant
somethingElse = something * TWIPS_PER_INCH; // a symbolic one
The first is an example of the magic constant, it conveys no other information other than its value.
The latter is far more useful since the intent is clear.
Using symbolic constant also helps a great deal if you have multiple things with the same value:
static const int TWIPS_PER_INCH = 1440;
static const int SECTORS_PER_FLOPPY = 1440; // showing my age here :-)
That way, if one of them changes, you can easily identify which single 1440 in the code has to change. With magic 1440s scattered throughout the code, you have to change it in multiple places and figure out which are the twips and which are the sectors.
A magic constant would be a numeric value that you just type into some code with no explanation about why it is there. Coming up with a good example is challenging. But let's try this:
float areaOfCircle(float radius) {
return radius * radius * 3.14159
}
Here I've used a "magic constant" of 3.14159 without any explanation of where it comes from. It would be better style to say
const float pi = 3.14159
float areaOfCircle(float radius) {
return radius * radius * pi;
}
Here I've given the person reading the code some idea about where the constant came from and why it was used... it didn't seem to "magically" appear out of nowhere.
Magic:
int DeepThought() { return 42; }
Symbolic:
const int TheAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything = 42;
int DeepThought() { return TheAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything; }
I'm currently getting into more C++11 stuff and jumped about constexpr. In one of my books it's said that you should use it for constants like π for example in this way:
#include <cmath>
// (...)
constexpr double PI = atan(1) * 4;
Now I wanted to put that in an own namespace, eg. MathC:
// config.h
#include <cmath>
namespace MathC {
constexpr double PI = atan(1) * 4;
// further declarations here
}
...but here IntelliSense says function call must have a constant value in a constant expression.
When I declare PI the following way, it works:
static const double PI = atan(1) * 4;
What is the actual reason the compiler doesn't seem to like constexpr but static const here? Shouldn't constexpr be eligible here, too, or is it all about the context here and constexprshouldn't be declared outside of functions?
Thank you.
What is the actual reason the compiler doesn't seem to like constexpr but static const here?
A constexpr must be evaluatable at compile time while static const does not need to be.
static const double PI = atan(1) * 4;
simply tells the compiler that PI may not be modified once it is initialized but it may be initialized at run time.
I have code which has a lot of conversions from double to int . The code can be seen as
double n = 5.78;
int d = n; // double implicitly converted to a int
The implicit conversion from double to int is that of a truncation which means 5.78 will be saved as 5 . However it has been decided to change this behavior with custom rounding off .
One approach to such problem would be to have your own DOUBLE and INT data types and use conversion operators but alas my code is big and I am not allowed to do much changes . Another approach i thought of was to add 0.5 in each of the numbers but alas the code is big and i was changing too much .
What can be a simple approach to change double to int conversion behaviour which impact the whole code.
You can use uniform initialization syntax to forbid narrowing conversions:
double a;
int b{a}; // error
If you don't want that, you can use std::round function (or its sisters std::ceil/std::floor/std::trunc):
int b = std::round(a);
If you want minimal diff changes, here's what you can do. Please note, though, that this is a bad solution (if it can be named that), and much more likely leaving you crashing and burning due to undefined behavior than actually solving real problems.
Define your custom Int type that handles conversions the way you want it to:
class MyInt
{
//...
};
then evilly replace each occurence of int with MyInt with the help of preprocessor black magic:
#define int MyInt
Problems:
if you accidentally change definitions in the standard library - you're in the UB-land
if you change the return type of main - you're in the UB-land
if you change the definition of a function but not it's forward declarations - you're in the UB/linker error land. Or in the silently-calling-different-overload-land.
probably more.
Do something like this:
#include <iostream>
using namespace std;
int myConvert (double rhs)
{
int answer = (int)rhs; //do something fancier here to meet your needs
return answer;
}
int main()
{
double n = 5.78;
int d = myConvert(n);
cout << "d = " << d << endl;
return 0;
}
You can make myConvert as fancy as you want. Otherwise, you could define your own class for int (e.g. myInt class) and overload the = operator to do the right conversion.