#include <iostream>
#include<Windows.h>
#define LENGTH 10;
#define NEWLINE '\n'
using namespace std;
int main(){
int area;
const int WIDTH=20;
area=LENGTH*WIDTH;
cout<<area<<NEWLINE;
system("pause");
}
Error is at line where area is calculated, it says "
operand of * must be a pointer
You should not terminate the macro definitions with ;. Otherwise the expression expands to:
area=10;*WIDTH;
Now the error makes sense, right?
#define LENGTH 10;
should be
#define LENGTH 10
// ^ no trailing ;
At present, the preprocessor expands your code to
area=10;*WIDTH;
// ^ error
Never, ever, terminate a macro with a semicolon.
#define LENGTH 10
is what you need.
Macros are simple text replacements.
Your macro LENGTH expands to the tokens 10;.
Then your statement in main is actually two statements:
area = LENGTH; *WIDTH
This attempts to dereference WIDTH, which is not a pointer and therefore cannot be dereferenced.
Your definition includes a semicolon which would normally end the statement.
#define LENGTH 10;
Remove the semicolon.
Exists error in your LENGTH macros, remove semicolon.
Good: #define LENGTH 10
Use the std::endl for carriage return.
std::cout<< area << std::endl;
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
I want to create a macro that replaces all calls to printf, more specifically mbedtls_printf (which behaves the exact sameway as printf) with nothing.
I know I can use #define mbedtls_printf to replace mbedtls_printf with nothing, but this will still leave the parameters/parenthesis intact.
Edit - I forgot to mention that mbedtls_printf is a macro that replaces itself with sgx_printf
I would go with:
#define printf(...) (0)
The benefit here is that it will continue to compile in cases where someone actually bothers to check the return from printf (rare but not unheard of).
The following works, at least with gcc 8. A brief search suggests that variadic macros were introduced with C99:
#define printf(...) do { } while (0)
int main()
{
printf("Hello %s?\n", "world");
return 0;
}
You want to use the ol' "do {} while (0)" trick, in order to avoid surprises like:
if (something)
printf("Something else");
will_this_be_invoked_or_not();
You can't make printf() disappear completely. Because this would make the next line a logical part of the preceding if statement. Hillarity ensues. That's why you still have to leave something in place.
If you completely no-op out the printf statements, there may be a bug lurking. Consider the following code:
printf("Result is %d\n", DoSomethingVeryImportant());
When you replace the printf call with a macro, you likely still want to make sure the inner function call to DoSomethingVeryImportant() is invoked. Otherwise, you've changed the logic of your program.
And I suppose you might want to have your mbedtls_printf actually call printf for debug builds, but be a no-op in a retail build.
If all of the above is of value, consider this as mbedtls_printf.h:
#ifndef MBEDTLS_PRINTF_H
#define MBEDTLS_PRINTF_H
#include <stdarg.h>
#include <stdio.h>
#ifdef DEBUG_BUILD
inline int printf_stub(const char* s, ...)
{
va_list args;
va_start(args, s);
vprintf(s, args);
va_end(args);
}
#define mbedtls_printf(...) printf_stub(__VA_ARGS__)
#else
inline int printf_stub(...){return 1;}
#define mbedtls_printf(...) printf_stub(__VA_ARGS__)
#endif
#endif
Then in code:
#include <iostream>
#include "mbedtls_printf.h"
int ImportantFunction()
{
std::cout << "Really important code" << std::endl;
return 42;
}
int main()
{
mbedtls_printf("Result of a very important step: %d\n", ImportantFunction());
mbedtls_printf("This just happened");
mbedtls_printf("Result of a another important step: ", 43, 44, ImportantFunction());
return 0;
}
The compiler will optimize out the empty function call and still invoke ImportantFunction() as it was doing originally.
I know I can use #define mbedtls_printf to replace mbedtls_printf with nothing, but this will still leave the parameters/parenthesis intact.
It's OK if the argument list remains, because then it will be treated as an expression. If we have an expression and we do nothing to it, then it will just be optimized out (on any decent compiler). Consider the following:
int x(char a, double b)
{
return printf("%c %f\n", a, b);
}
#define x
int main(void)
{
x('P', 3.14);
}
The compiler sees the following code for main:
('P', 3.14);
This expression evaluates to 3.14 (the comma operator returns its right-hand operand). Such an expression is quietly optimized.
Just use a lambda: (Variadic macros since C99)
#define printf(...) []{}()
What this does is simply replace the printf() calls to []{}()... This just means an empty function call... which can be formatted to be like this:
#define printf(...) [] { \
}()
Or, even this suffices:
// Replacing printf() with an empty function that just takes variadic arguments
#define printf [](...){}
Edit: You can also use:
#define printf void(0)
I am trying to benchmark a large number of functions, and I have defined macros to generalise the time stamping. I have made a header file benchmarking.h as follows:
#include <chrono>
#include <iostream>
#define START(x) xstart = std::chrono::steady_clock::now()
#define END(x) xend = std::chrono::steady_clock::now()
#define TIME(x) xtime = std::chrono::duration_cast<std::chrono::nanoseconds>(xend-xstart).count()
#define PRINT(x) std::cout << #x << "(), " << xtime << std::endl
This for all macros, x is substituted with the function name, without parameter brackets. e.g PRINT(foobar); etc.
However, I have used the same macros for multiple function names, as I thought that I could substitute x multiple times.
i.e.
START(foobar);
// later...
START(func);
However, I get an error:
xstart’ has a previous declaration as ‘std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration\<long int, std::ratio<1l, 1000000000l> > > xstart
It seems like I cannot reuse the variable once I have used it to define a function.
However, I never get this error with PRINT. So, is it because I am declaring variables?
I am basically trying to come up with a fast way to timestamp functions, so any other suggestions on how to achieve this quickly are welcome.
You need to use the macro token concatenation operator ##:
#define START(x) x ## start = std::chrono::steady_clock::now()
and similarly for the other macros.
When you just write xstart, the x is not replaced with the macro argument, but xstart is left as is. Argument substitution only operates on single identifiers; they cannot be part of a larger word.
I would like to ask why this code prints out 2 instead of 0. Doesn't #define "assign" values to the names of the macros and calculate also the result? How does it give this answer?
#include <iostream>
using namespace std;
#define A 0
#define B A+1
#define C 1-B
int main() {
cout << C<<endl;
return 0;
}
Macros are direct text replacements That means
#define C 1-B
becomes
1-A+1
and then A gets expanded so we have
1-0+1
which is 2. If you want 0 then stop using macros and instead use constant variables
const int A = 0;
const int B = A + 1;
const int C = 1 - B;
And now C is 0.
The preprocessor expands the C macro to 1-B, which expands to 1-A+1 which expands to 1-0+1 which equals 2. Don't think of it in terms of sequential assignment, but you can get the desired behavior by adding parenthesis around the macro definitions. Then the C macro would expand to (1-B), then (1-(A+1)) then (1-((0)+1)) which equals 0.
Edit:
As an example, the code snip below prints 42, even though BAR is "assigned" to FOO when FOO equals 17. This is because the expansion is deferred until it's actually used. On the cout line, BAR is still equal to FOO, but at that point, FOO is now 42, not 17. Note that it's bad practice to redefine a macro without first #undefining it.
#define FOO 17
#define BAR FOO
#define FOO 42
cout << BAR << endl;
Because C expands to 1-0+1
Preprocessor defines simply replace text and don't care about operator precedence or calculation rules.
Here is some C++ code I'm playing around with:
#include <iostream>
#include <vector>
#define IN ,
#define FOREACH(x,y) for(unsigned int i=0;i<y.size();i++) { x=y[i];
#define ENDFOREACH }
using namespace std;
int main()
{
vector<int> ints;
ints.push_back(3);
ints.push_back(4);
ints.push_back(5);
ints.push_back(6);
FOREACH(int item IN ints)
cout << item;
ENDFOREACH
return 0;
}
However, I get an error:
macro "FOREACH" requires 2 arguments, but only 1 given
The code compiles if I change the IN to a comma. How can I get the IN to take the place of a comma?
Update: for those interested, here is the final version, which, if I do say so myself, is quite nice.
#include <iostream>
#include <vector>
#define in ,
#define as ,
#define FOREACH_(x,y,z) \
y x; \
if(z.size()) x = z[0]; \
for(unsigned int i=0,item;i<z.size();i++,x=z[i])
#define foreach(x) FOREACH_(x)
using namespace std;
int main()
{
vector<int> ints;
ints.push_back(3);
ints.push_back(4);
ints.push_back(5);
ints.push_back(6);
foreach(item as int in ints)
{
cout << item << endl;
}
return 0;
}
Others have already explained why it doesn't compile as is.
In order to make it work you have to give that IN a chance to turn into a comma. For that you can introduce an extra level of "indirection" in your macro definition
#define IN ,
#define FOREACH_(x,y) for(unsigned int i=0;i<y.size();i++) { x=y[i];
#define FOREACH(x) FOREACH_(x)
#define ENDFOREACH }
In this case you'll have to use some substitute for comma (like your IN) and can no longer specify comma explicitly. I.e. now this
FOREACH(int item IN ints)
cout << item;
ENDFOREACH
compiles fine, while
FOREACH(int item, ints)
cout << item;
ENDFOREACH
does not.
The compiler doesn't expand the IN macro before it reads the arguments to FOREACH. In fact, I think this is intentional (so that you can pass a comma to a macro).
Unfortunately, you'll have to use FOREACH(int item, ints).
You could also #define IN (make it nothing) and then use FOREACH(int item, IN ints), which is not quite as nice, but is acceptable.
That said, you may just want to use STL or Boost for foreach, unless you specifically want to create your own.
Expansion for IN doesn't happen early enough in your example, but you can pass the expanded version to another macro:
#define FOREACH(x) DO_FOREACH(x)
#define DO_FOREACH(x,y) for( ... ) ...
#define IN ,
#define XFOREACH(x,y) for(unsigned int i=0;i<y.size();i++) { x=y[i];
#define FOREACH(x) XFOREACH(x)
#define ENDFOREACH }
As previous posters have noted, the preprocessor does not expand macros in the arglist before it splits it into argument. However, as long as the macro doesn't use # or ##, it expands macros in the args before substituting them into the macro body, so an extra indirection does the trick
Check out BOOST_FOREACH - it does what you want
http://www.boost.org/doc/libs/1_35_0/doc/html/foreach.html
The preprocessor doesn't expand the IN to a comma until after it reads the arguments to FOREACH.
I'm pretty sure that the c++ preprocessor is one pass only, so you'll have to use:
FOREACH(int item, ints)
cout << item;
ENDFOREACH