I have this code , i need output x variable as double (3.14) without changing anything in the main function
#include <iostream>
int main() {
int x = 3.14;
std::cout << x << "\n";
return 0;
}
What should i do ?
There are two solutions, one correct and one your professor probably wants.
The correct solution (one method, there are other similar ones).
Add this right after the #include line:
int main() {
double x = 3.14;
std::cout << x << "\n";
return 0;
}
#if 0
Add this at the end of the file:
#endif
The incorrect solution for your professor.
Add this line before main:
#define int double
Why is this incorrect? Because #defineing a reserved word is undefined behaviour.
[macro.names] A translation unit shall not #define or #undef names lexically identical to keywords [...]
Why do I think your professor probably wants this? Because I've seen a few C++ assignments, and observed that their authors all too often disregard and abuse the C++ standard.
Your professor might want the first solution instead. I have no way to predict that.
Related
HI ,
Can some one help me in understanding why the value of SQUARE(x) is 49 ?
I am using Visual C++ 6.0 .
#define SQUARE(X) X * X
int main(int argc, char* argv[])
{
int y = 5;
printf("%d\n",SQUARE(++y));
return 0;
}
Neil Butterworth, Mark and Pavel are right.
SQUARE(++y) expands to ++y * ++y, which increments twice the value of y.
Another problem you could encounter: SQUARE(a + b) expands to a + b * a + b which is not (a+b)*(a+b) but a + (b * a) + b. You should take care of adding parentheses around elements when needed while defining macros: #define SQUARE(X) ((X) * (X)) is a bit less risky. (Ian Kemp wrote it first in his comment)
You could instead use an inline template function (no less efficient at runtime) like this one:
template <class T>
inline T square(T value)
{
return value*value;
}
You can check it works:
int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
(no need to write
square<int>(++i)
because the int type is implicit for i)
Because the macro expands to:
++y * ++y
which gives undefined behaviour in C++ - the result could
be anything. This very well known problem should be covered in any decent textbook that covers the use of macros. Which one are you using?
Because macros do textual substitution so the code you wrote gets expanded to
printf("%d\n",++y * ++y );
and then the order of operations is undefined behaviour so this the compiler sees 2 increments and then a multiplication
So be careful with macros better to use functions which as the compiler can expand inline will not take any longer to run.
Secondly don't assume what will happen if you increment and use variables
Macros are not functions: they just alter the text of the program. This operation is called preprocessing and it's automatically executed before your code gets compiled. People write macros to save their time and introduce some variability to their source code.
When you write SQUARE(x), no actual funciton call happens, just the text is modified. The operation is quite dumb, so you have to do additional precautions in cases like yours. Refer to other answers for explanation of your case.
If you look at the grammar for *declarator*s in §8/4 you'll notice that a noptr-declarator can be written as (ptr-declarator), that is, it can be written as (declarator-id), which validates declarations like the ones in the title. As matter of fact this code compiles without a problem:
#include <iostream>
struct A{ int i;};
int (x) = 100;
A (a) = {2};
int main()
{
std::cout << x << '\n';
std::cout << a.i << '\n';
}
But what is the purpose of allowing these parentheses when a pointer (to an array or to a function) is not involved in the declaration?
The fact that this rule is applicable in your case is not deliberate: It's ultimately a result of keeping the grammar simple. There is no incentive to prohibit declarations such as yours, but there are great disincentives to complicate rules, especially if those are intricate as they are.
In short, if you don't want to use this needlessly obfuscated syntax, don't.
C++ rarely forces you to write readable code.
Surprisingly there are scenarios in which parentheses can save the day, though:
std::string foo();
namespace detail
{
int foo(long); // Another foo
struct Bar
{
friend std::string ::foo(); // Doesn't compile for obvious reasons.
friend std::string (::foo)(); // Voilà!
};
}
You're asking the wrong question. The correct question is:
What is the purpose of disallowing such a declaration?
The answer is: there is none.
So, given that this syntax is allowed as a side-effect of rules elsewhere, this is what you get.
If I use this code outside of a method or winmain:
ostringstream vertexid;
vertexid << "bob";
vertexid << " ";
vertexid << " ";
vertexid << 48348093490;
I get all sorts of syntax errors. How does scope play into this why is this happening?
You can do something like this:
std::ostringstream ss;
#define nil(x) ((x), 0)
int x = nil(ss << "Hello");
int y = nil(ss << ", World!");
int z = nil(ss << std::endl);
If you really don't like thinking up variable names, then you can do something even crazier:
#define nilPASTE(x, y) x ## y
#define nilPASTE2(x, y) nilPASTE(x, y)
#define nil2(x) static int nilPASTE2(line_, __LINE__) = nil(x)
nil2(ss << "Goodbye");
nil2(ss << ", Sun!");
nil2(ss << std::endl);
You asked:
How does scope play into this why is this happening?
I assume you mention scope because that is what some error message spat out. But the answer to both parts of that question is that the C++ compiler is following the rules of the C++ language, which does not allow statements to just appear anywhere. They can only appear where they are allowed, which are in functions and method bodies. The reason my technique is allowed is because I am using expressions, and expressions can appear in more places. In particular, they are allowed to appear in an initializer to a variable. And of course, variable declarations are allowed on the outer most level of a translation unit.
All that gobbly gook means: put your statements inside functions and methods.
You can only declare or define stuff at global scope.
The first line alone would be OK (in an implementation file... if in a header, you risk having multiple definitions and would need to declare it as extern instead of defining it), the next lines are just not legal.
At global namespace you cannot have code, because when should it be executed? You can only put executable statements inside functions, for example WinMain/main.
The execution starts at WinMain/main, then you can call your other functions from there.
how does it work? are the variables stored in special registers or memory? im looking at the register/memory windows in visual but i cant understand it :(
#include <iostream>
using namespace std;
namespace first
{
int x = 5;
int y = 10;
}
namespace second
{
double x = 3.1416;
double y = 2.7183;
}
int main () {
using first::x;
using second::y;
cout << x << endl;
cout << y << endl;
cout << first::y << endl;
cout << second::x << endl;
return 0;
}
class CRectangle {
int x, y;
public:
void set_values (int,int);
int area (void);
private:
int param;
} rect;
From the machine's perspective, there's nothing different about private or namespace. Those are just identifiers for the compiler. That is, the compiler enforces access rules, which is why you get compiler errors for doing something you shouldn't. The binary code the compiler ultimately produces, however, doesn't make any distinction about what the data is.
The compiler takes
namespace first
{
int x = 5;
int y = 10;
}
namespace second
{
double x = 3.1416;
double y = 2.7183;
}
and effectively produces assembly code which works something like this:
_first##x: dd 5
_first##y: dd 10
_second##x: dq 3.1416
_second##y: dq 2.7183
In case you are not familiar with assembly language, these four statements each reserve memory, two for 32-bit integers, and two for a floating point values, and assign labels to them. A label is a memory address.
Note that the namespace qualifies each variable name. The # in itself it has no meaning, but escapes the namespace and variable name to isolate unusually named C++ language variables. Assembly language identifiers typically allow a greater range of characters in them than high level languages, convenient in usages such as this.
Namespaces are used as direction for compiler, as actual var names and method/class names have different name after compilation, so namespace name is not used.
HI ,
Can some one help me in understanding why the value of SQUARE(x) is 49 ?
I am using Visual C++ 6.0 .
#define SQUARE(X) X * X
int main(int argc, char* argv[])
{
int y = 5;
printf("%d\n",SQUARE(++y));
return 0;
}
Neil Butterworth, Mark and Pavel are right.
SQUARE(++y) expands to ++y * ++y, which increments twice the value of y.
Another problem you could encounter: SQUARE(a + b) expands to a + b * a + b which is not (a+b)*(a+b) but a + (b * a) + b. You should take care of adding parentheses around elements when needed while defining macros: #define SQUARE(X) ((X) * (X)) is a bit less risky. (Ian Kemp wrote it first in his comment)
You could instead use an inline template function (no less efficient at runtime) like this one:
template <class T>
inline T square(T value)
{
return value*value;
}
You can check it works:
int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
(no need to write
square<int>(++i)
because the int type is implicit for i)
Because the macro expands to:
++y * ++y
which gives undefined behaviour in C++ - the result could
be anything. This very well known problem should be covered in any decent textbook that covers the use of macros. Which one are you using?
Because macros do textual substitution so the code you wrote gets expanded to
printf("%d\n",++y * ++y );
and then the order of operations is undefined behaviour so this the compiler sees 2 increments and then a multiplication
So be careful with macros better to use functions which as the compiler can expand inline will not take any longer to run.
Secondly don't assume what will happen if you increment and use variables
Macros are not functions: they just alter the text of the program. This operation is called preprocessing and it's automatically executed before your code gets compiled. People write macros to save their time and introduce some variability to their source code.
When you write SQUARE(x), no actual funciton call happens, just the text is modified. The operation is quite dumb, so you have to do additional precautions in cases like yours. Refer to other answers for explanation of your case.