Solved

C++: Passing bool variable to a function

Posted on 2014-07-22
21
4,359 Views
Last Modified: 2014-07-24
I have a code which looks like foll.
//declaration
bool IsMultiple( int* bOK, bool bMultiple = false ) 
//implementation
#include <iostream>
#include <iomanip>
bool IsMultiple( int* bOK, bool bMultiple )
{
  *bOK = false;
   //some processing
    bMultiple = true;
   if(bMultiple)
   {
        *bOK = true;
        return true;
   }
   return false;
}
 
int main()
 {
 
    bool bMultiple = false;
    bool bRet = IsMultiple(bMultiple );
    std::cout << bMultiple << std::endl; // prints always false, even if set true in function
    //call again
    bool cRet = IsMultiple(); //bMultiple is default
    std::cout << bMultiple << std::endl;  // same deal
    return 0;
}

Open in new window

The function changes the value of bool argument, however back in main function bool variable reverts to original value(false). What is happening? How to fix?
Thanks.
0
Comment
Question by:vakils
  • 9
  • 8
  • 3
  • +1
21 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 40212810
This snippet should not even compile, You are declarin a function that takes an 'int*', but you ar passing  'bool' by value. If you meant to pass its address as a pointer, you should use

//declaration
bool IsMultiple( bool* bOK, bool bMultiple = false );

//...

bool bRet = IsMultiple(&bMultiple ); // <-- important: use '&' here

Open in new window


which  I assume would fix your initial problem.

Also, the statement

bool cRet = IsMultiple(); //bMultiple is default

Open in new window


will not compile, since the 2nd parameter has a default, but the 1st hasn't.

To sum that up, this here should do what you want:

//declaration
bool IsMultiple( bool* bOK, bool bMultiple = false );
//implementation
#include <iostream>
#include <iomanip>
bool IsMultiple( bool* bOK, bool bMultiple )
{
  *bOK = false;
   //some processing
    bMultiple = true;
   if(bMultiple)
   {
        *bOK = true;
        return true;
   }
   return false;
}
 
int main()
 {
 
    bool bMultiple = false;
    bool bRet = IsMultiple(&bMultiple );
    std::cout << bMultiple << std::endl; 
    //call again
    bool cRet = IsMultiple(&bMultiple); //bMultiple is default - but NOT the 1st parameter, only the 2nd one
    std::cout << bMultiple << std::endl;  
    return 0;
}

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 40212816
BTW, you might want to consider using a reference instead of a pointer here, e.g.

//declaration
bool IsMultiple( bool& bOK, bool bMultiple = false );
//implementation
#include <iostream>
#include <iomanip>
bool IsMultiple( bool& bOK, bool bMultiple )
{
   bOK = false;
   //some processing
    bMultiple = true;
   if(bMultiple)
   {
        bOK = true;
        return true;
   }
   return false;
}
 
int main()
 {
 
    bool bMultiple = false;
    bool bRet = IsMultiple(bMultiple ); // now you can call it without using '&'
    std::cout << bMultiple << std::endl; 
    //call again
    bool cRet = IsMultiple(bMultiple); //bMultiple is default - but NOT the 1st parameter, only the 2nd one
    std::cout << bMultiple << std::endl;  
    return 0;
}
                    

Open in new window

0
 

Author Comment

by:vakils
ID: 40213091
bool cRet = IsMultiple(bMultiple); //bMultiple is default - but NOT the 1st parameter, only the 2nd on
You are passing bMultiple by value, where is reference? bMultiple will get assigned to first param(bOK) as it is not default and so I won't be able to get bMultiple value processed from function. The function is designed so that it could return with bOK true, but bMultiple false.
0
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
LVL 86

Expert Comment

by:jkr
ID: 40213236
>> You are passing bMultiple by value, where is reference?

References don't need to be declared as such when calling the function in question, the declaration will take care of the correct behaviour, so you won't have to worry. BTW, did the 1st snippet that still uses pointers work for you?
0
 

Author Comment

by:vakils
ID: 40213252
Yes, the first one worked. The second didn't.
0
 
LVL 86

Expert Comment

by:jkr
ID: 40213266
Weird, it gave me the same output when I ran it here... and it still does after double checking that with the above snippets. Is there anything you might have changed?
0
 

Author Comment

by:vakils
ID: 40213309
I will try with a small app and check.  Shouldn't function be declared as
IsMultiple (bool& bOK, bool& bMultiple = false);
0
 
LVL 8

Expert Comment

by:Subrat (C++ windows/Linux)
ID: 40213333
Can you paste the complete code here? It seems you are doing something wrong there.
JKR's suggestion is valid.
0
 
LVL 8

Expert Comment

by:Subrat (C++ windows/Linux)
ID: 40213345
>> Shouldn't function be declared as IsMultiple (bool& bOK, bool& bMultiple = false);
No.
It should be
bool IsMultiple (bool& bOK, bool bMultiple = false);
If using reference as parameter to a function, you can't use default argument for that parameter. There will be a conversion issue from bool to bool&.
0
 
LVL 8

Expert Comment

by:Subrat (C++ windows/Linux)
ID: 40213351
To understand, why conversion is not possible, consider following examples.

bool fun(int* p); // Valid
bool fun2(int* p = 0); // Valid - here it's pointing to nothing
bool fun2(int* p = 1); // Invalid, here we are trying to assign a integer to an address where an address is expected

So if really you want this feature, you need to do a type casting. I hope type casting  will not throw any error.(Not tested)

FYI: Reference is nothing but a constant pointer.
0
 
LVL 33

Expert Comment

by:sarabande
ID: 40213927
to add to above comments:

to pass bOk as an output argument seems to be unnecessary. the ok should be the return value. as you want to have the bMultiple returned you need to define it and can initialize it with the default:

// function declaration
bool IsMultiple(bool & bMultiple);

....
bool bMultiple = false;  
bool bok = IsMultiple(bMultiple);  

Open in new window

that looks better now but is still bad code. an "Is..."-function should not return an ok but should return the answer to the the "Is..." question. all other is badly readable and should be avoided. so your final code should be like

bool IsMultiple(int num1, int num2)
{
       bool bMultiple = false;
       if (num1 != 0 && num2 != 0)
       {
              int d = num2/num1;
              bMultiple = (d*num1 == num2);
       }
        return bMultiple;
}

Open in new window


now the IsMultiple is well-defined and could be used like

if (IsMultiple(6, 18))
{
      ...

Open in new window


Sara
0
 

Author Comment

by:vakils
ID: 40215213
JKR,
Your code works because bMultiple gets assigned to bOK in function, which  takes &bOK and that arg is not default. The correct version of your code should be below, which shows the original behavior and my problem: bMultiple reverts back to false (original value).
//declaration
bool IsMultiple( bool& bOK, bool bMultiple = false );
//implementation
#include <iostream>
#include <iomanip>
bool IsMultiple( bool& bOK, bool bMultiple )
{
   bOK = false;
   //some processing
    bMultiple = true;
   if(bMultiple)
   {
        bOK = true;
        return true;
   }
   return false;
}
 
int main()
 {
 
    bool bMultiple = false;
	bool bOK = false;
    bool bRet = IsMultiple(bOK, bMultiple ); // now you can call it without using '&'
    std::cout << "bOK=" << bOK << "bMultiple=" <<bMultiple << std::endl; 
    //call again
    bool cRet = IsMultiple(bOK); //bMultiple is default - but NOT the 1st parameter, only the 2nd one
    std::cout << "bOK=" << bOK << std::endl;  
    return 0;
}

Open in new window

                   
Output
bOK=1bMultiple=0
bOK=1

Open in new window


If I define function:
bool IsMultiple( bool& bOK, bool& bMultiple = false );      

Open in new window

 
I get compilation error.
How would you get around that?
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 40215275
The reason that 'bMultiple' does not change is either code snippet is that you are effectively passing it by value, which will not reflect any changes in the calling function.

>>I get compilation error.
>>How would you get around that?

You can't use default parameters with references - that is because a default parameter basically means that the compiler provides an non-assignable value. The only way is to not use a default value, e.g.

bool IsMultiple( bool& bOK, bool& bMultiple);
//implementation
#include <iostream>
#include <iomanip>
bool IsMultiple( bool& bOK, bool& bMultiple )
{
   bOK = false;
   //some processing
    bMultiple = true;
   if(bMultiple)
   {
        bOK = true;
        return true;
   }
   return false;
}
 
int main()
 {
 
    bool bMultiple = false;
	bool bOK = false;
    bool bRet = IsMultiple(bOK, bMultiple ); 
    std::cout << "bOK=" << bOK << "bMultiple=" <<bMultiple << std::endl; 
    //call again
    bool cRet = IsMultiple(bOK, bMultiple); 
    std::cout << "bOK=" << bOK << std::endl;  
    return 0;
}
                                                        

Open in new window

0
 

Author Comment

by:vakils
ID: 40215660
Why it works with pointers? What are the semantics between pointers and references ( as you can pass reference and modify that in function)
0
 
LVL 86

Expert Comment

by:jkr
ID: 40215679
Pointers and references are different concepts, even though they seem so similar, see e.g. http://en.wikipedia.org/wiki/Reference_(C++)#Relationship_to_pointers

Think of it as a logical link, whereas a pointer is a physical link to the memory area an object or variable resides in. This however implies some limitations, such as they cannot be used with default parameters in function calls.
0
 

Author Comment

by:vakils
ID: 40215722
OK. Got it. Reference has to point to something. I found foll. workaround works:
bool bRetn = 1; //global scope
bool IsMultiple( bool& bOK,  bool& bMultiple = bRetn); // Now ref has something to refer to
0
 

Author Comment

by:vakils
ID: 40215849
Subrat,
FYI: Reference is nothing but a constant pointer.
If that is so, how can we modify its value from a function?
0
 
LVL 86

Expert Comment

by:jkr
ID: 40215859
It is not a 'constant pointer' - it's a link that cannot be 'reseated' (as the Wikipedia article puts it - or be reassigned, which would be my choice of wording). There are const references as well, but that also is different and you'd usually use that to pass a reference to 'something big' (i.e. an object too large to pass it via the call stack) without the option that the callee can modify it.
0
 

Author Comment

by:vakils
ID: 40215870
OK. Thanks I learned a lot. Brushed up on C++. Reference is me, watching my boss's(object) seat(location). I cannot watch anybody else, boss can change (if not const) but seat remains same! How about that analogy. And of course I modified my code accordingly.
0
 
LVL 86

Expert Comment

by:jkr
ID: 40215874
Nice analogy ;-)

I wished you were able to present more than a model of your problem, so se would have addressed it more directly,,,
0
 

Author Comment

by:vakils
ID: 40217855
It's a Visual Studio MFC application. So taking code out of context will not compile and would add to confusion. So I posted close approximation of the problem ( Whether reference can be a default parm) which would compile and I would understand your solution.
0

Featured Post

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
how to understand recursion 12 226
VS2015 compilation and missing DLLs 9 147
Unable to start eclipse ? 17 141
How can i compile this github project?? 2 83
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question