C++ : prim() in an "if statement" - c++

While studying the C++ programming language by B. Stroustrup, it has been mentioned the existence of the prim() functions which reduces the scope of the declared variable to one single block.
This is an example provided by the book:
if (double d = prim(true)) {
left /= d; break;
}
Despite understanding its interest, I cannot figure out how to use it: is it part of a certain library ? Of must I precise the standard because Visual Studio isn't able to recognise the function.
Thanks in advance

The code demonstrates an ability to declare a local variable inside a header of an if statement. It has nothing to do with prim(...) function, which is probably defined in some other place in the book.
Here is another example:
int k = 3;
if (int d = k*50) {
cout << "hello " << d << endl;
}
This prints hello 150. Variable d is accessible only inside the body of the if statement.
Note that the scope of d extends to else branch as well (demo):
int k = 0;
if (int d = k*50) {
cout << "hello " << d << endl;
} else {
cout << "goodbye " << d << endl;
}
Note: In the example above there is no reason to check d in the else branch because it is guaranteed to be zero.

There is no prim() function in the standard library. It is a user defined function used to demonstrate that the condition in the if statement can be a declaration. The function itself is defined in Section 10.2.1 on page no. 245.

Related

C++ program behaviour differs when compiled with Cygwin and MinGW

I am fairly new to C++ and have been tinkering with some simple programs to teach myself the basics. I remember a little while ago installing MinGW on my desktop (I think for the C compiler). I decided to go for Cygwin for C++ and it seems to have been working a treat, up until I noticed that it seems to behave differently from the MinGW compiler for this program. I'm probably breaking some coding golden rule, but the reason for this is that Windows CMD uses the MinGW compiler, or I can open the Cygwin shell and use that instead. Variety!
For the program below, I am making notes on the ternary operator and switch statement. I initialize 'a' and 'b', ask for user input, and then use a function to check which is larger.
I then ask for user input again, to over-write the values in 'a' and 'b' to something else. When compiling from Windows CMD, this works fine and I can overwrite with new input, and the #define MAXIMUM and MINIMUM functions work fine on the new values. When I compile on Cygwin, however, after the first 'pause', the program launches past the two std::cin's and just runs MAXIMUM and MINIMUM on the old values of 'a' and 'b'.
Obviously I have tried just creating two new int variables, 'c' and 'd', and then there is no issue. The values are not immutable in any sense that I am aware of (although I don't know much, so I could be wrong).
I wasn't sure if this was something to do with the auto keyword, so I specified the type as int manually.
I also checked the version of both compilers with 'g++ -v' in Cygwin and at the CMD.
#include <iostream>
#include <cstdlib>
#define MAXIMUM(a,b) ((a > b) ? a : b)
#define MINIMUM(a,b) ((a < b) ? a : b)
int ternary_op(int a, int b)
{
char x = 'a';
char y = 'b';
auto result_var = 0;
result_var = a > b ? x : y; //Shorthand if statement with syntax (test_condition) ? (if_true) : (if_false)
return result_var;
}
int main()
{
auto a = 0;
auto b = 0;
auto larger = 0;
auto smaller = 0;
std::cout << "Enter an integer: " << "\n";
std::cin >> a;
std::cout << "Enter another integer: " << "\n";
std::cin >> b;
char greater_var = ternary_op(a,b); //Therefore if condition a > b is satisfied, greater_var is assigned x ('a')
std::cout << greater_var << std::endl;
switch(greater_var){
case 'a':
std::cout << "First integer " << a << " is larger than second, " << b << std::endl;
break;
case 'b':
std::cout << "Second integer " << b << " is larger than first integer, " << a << std::endl;
break;
}
std::cout << system("cmd /c pause") << std::endl;
std::cout << "We can also use defined functions to check equivalency and assign variables based upon the result." << "\n";
std::cout << "Enter an integer: " << std::endl;
std::cin >> a;
std::cout << "Enter another integer: " << std::endl;
std::cin >> b;
larger = MAXIMUM(a,b);
smaller = MINIMUM(a,b);
std::cout << "Larger and smaller numbers determined by defined function: " << larger << ", " << smaller << std::endl;
std::cout << system("cmd /c pause") << std::endl;
return 0;
}
Obviously if I make two new variables, 'c' and 'd', there is no issue. Changing the type to int myself did not change the way the program behaved using Cygwin. Unusually the MinGW version was 8.1.0, while Cygwin was 7.4.0. I'm not sure if this means that it is simply an older version of the same compiler.
Again, I'm very new to this so I'm just quite confused as to why they would behave so differently. I was also under the impression that different compilers were completely different beasts that simply read from the same standard hymn sheet, so to speak.
Just curious as to what is going on here!
Cheers!

Local variable initialized in a condition not recognized?

I am learning c++ and I came across a really odd phenomenon in a program. I haven't seen any documentation on this problem. Why is that when I initialize a variable inside of a conditional statement it isn't recognized outside of it? Is the variable local to the conditional statement?
Here is an example:
#include "stdafx.h"
#include <iostream>
using namespace std;
/*scope / range of variables */
int global;
int main()
{
int local = rand();
cout << "value of global " << global << endl;
cout << "value of local " << local << endl;
int test = 10;
if (test == 0)
{
int result = test * 10;
}
cout << "result :" << result << endl;
return 0;
}
In this case result is undefined. Can someone please explain what is going on?
As pointed out in the comments, your declaration of result is local inside the if() blocks scope you provided:
if (test == 0)
{ // Defines visibility of any declarations made inside
int result = test * 10;
} // ^^^^^^
Hence the statement
cout << "result :" << result << endl;
would lead to a compiler error, since result isn't visible for the compiler at this point outside that scope.
But even if you declare result correctly outside of the scope block, your logic
int result = 0; // Presumed for correctness
int test = 10;
if (test == 0)
{
result = test * 10; // Note the removed declaration
}
doesn't make much sense, since test was given the value 10 immediately before testing it against the value 0 in your your if() statements condition, and the condition never would become true.

evaluation of passed parameters in macros

#define prod(a) (a*a)
using namespace std;
int main()
{
int i = 3, j, k, l;
j = prod(i++);
cout << i << endl;
k = prod(++i);
cout << i << endl;
l = prod(i+1);
cout << i << " " << j << " " << k << " " << l;
}
Why is variable "i" incremented twice?
i.e to 5 from 3 after j=prod(i++);
Remember that macros are expanded in the source code, not actually called or evaluated.
That means a "call" like
prod(i++)
results in the expanded code
i++*i++
being seen by the compiler.
Many compilers allow you to stop after preprocessing, or otherwise generate preprocessed source, that you can examine to see macro expansions.
If you continue using such a macro with other expressions as arguments, you will soon see another reason they are bad.
Lets say you use
prod(2+4)
Then that will result in the expansion
2+4*2+4
which is equal to
2+(4*2)+4
which is equal to 14, not 36 which might have been expected.
Why is variable "i" incremented twice? i.e to 5 from 3 after j=prod(i++)
Because prod() is a macro, not a function, so
k=prod(++i);
become
k=(++i * ++i);

Access variable that was overwritten within given scope via function that uses global variables

I have this piece of code:
#include <stdio.h>
// global variable definition
int x = 0;
void access_global(){
cout << "ACCESSING FROM access_global()" << endl;
if (x > 0){
cout << "LOCAL VARIABLE" << endl;
cout << x << endl;
}
else{
cout << "GLOBAL VARIABLE" << endl;
cout << x << endl;
}
}
int main(int, char*[])
{
// declare new variable in given scope with same name as global variable
int x = 1;
cout << "ACCESSING FROM main()" << endl;
if (x > 0){
cout << "LOCAL VARIABLE" << endl;
cout << x << endl;
}
else{
cout << "GLOBAL VARIABLE" << endl;
cout << x << endl;
}
access_global();
return 0;
}
It outputs:
ACCESSING FROM main()
LOCAL VARIABLE
1
ACCESSING FROM access_global()
GLOBAL VARIABLE
0
Why is access_global() not accessing x in the main() scope?
Is it possible to modify access_global() function that it will show primary x variables from main() scope and if they are not defined then show those defined outside of main()? If is not possible can you please explain why? Thanks
Why is access_global() not accessing x in the main() scope?
Because main::x is not in scope in access_global. Fortunately, names don't just "leak" out of functions' scopes. The global x is the only x it can see.
Is it possible to modify access_global() function that it will show primary x variables from main() scope and if they are not defined then show those defined outside of main()?
Not in the way you are hoping to, no. The names in main are not related to the names in access_global in any sense.
If is not possible can you please explain why?
As usual: Because the standard says so. Why it does that is subject to some speculation, but it would certainly be extremely confusing if the meaning of some function changed depending on what names exist in the calling context, something you usually don't control when writing a function.
Just think what would happen if access_global was called once from a function that has some x, possibly not even of type int, and once from some function that does not have a local x: You could not predict what the function does at all without looking at all callers. That's very much impractical.

How to create a variable in a if statement body in C++

I am trying to create a integer variable in a if statement body like this:
if (a == 72){
cout <<"You Are CORRECT1"<<endl;
int aa = 1;
}
else{
cout <<"No. The answer is "<<12*6<<endl;
int aa = 2;
}
When I compile this it says:
42 C:\Documents and Settings\Valued Customer\Desktop\C++\Variable.cpp aa undeclared (first use this function)
Could you please help me.
Declare the variable before like so.
int aa;
if (a == 72)
{
cout <<"You Are CORRECT1"<<endl;
aa = 1;
}
else{
cout <<"No. The answer is "<<12*6<<endl;
aa = 2;
}
Your variable declaration is correct, the problem ís that the lifetime of your variable is only valid inside the block in which it was declared. Any attempts to use it outside this block is invalid.
You can use the conditional operator for this kind of situation:
int aa = a == 72 ? 1 : 2;
This allows you to initialize a variable based on a condition, something which cannot be done with an if-else statement. You will have to deal with writing to stdout separately though.
It's likely telling you this when you're outside of your if/else statement. In the example you give, you're creating local variables inside the scope of the if and the else. They go out of scope and "cease to exist" after the if / else stuff.
Here's the way you should do it:
int aa = -1;
if (a = 72)
{
cout << "You are CORRECT1" << endl;
aa = 1;
}
else
{
cout << "No. The answer is " << 12 * 6 << endl;
aa = 2;
}
cout << aa << endl;
By doing it this way, you declare the int outside of the scope of the if/else code block, so the variable continues to survive, and can be accessed outside of that code block.