Thread: Is it possible to make this int const?

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    519

    Is it possible to make this int const?

    Hi,

    do you know any workaround to make the integer UNIT const?

    Code:
    	int UNIT;
    	try
    	{
    		UNIT = boost::lexical_cast<int>(argv[2]);
    	}
    	catch(const boost::bad_lexical_cast&)
    	{
    		cout << "Usage: input_file.bmp granularity(1..inf)" << endl;
    		exit(EXIT_FAILURE);
    	}
    It can't be declared const, because then it can't get its assignment inside the try block. And also it can't be declared inside the try-block, because then it's bound to the scope try defines.

    Thank you in advance!

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Not that used to messing around with try/catch, but maybe wrap the try/catch in a function. If the code in the catch block is run, then you already exit the program; if not, you can return the converted value to the caller which can immediately assign it to a const int.
    Code:
    int foo(char * arg)
    {
        int temp;
        try
        {
            temp = boost::lexical_cast<int>(arg);
        }
        catch(const boost::bad_lexical_cast&)
        {
            cout << "Usage: input_file.bmp granularity(1..inf)" << endl;
            exit(EXIT_FAILURE);
        }
        return temp;
    }
    
    ...
    
    const int UINT = foo(argv[2]);
    Maybe, maybe not? Just an idea.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    it can't be a const, because you are assigning it a value inside the try.

    You could perhaps do soemthing like this:
    Code:
    int func() {
    	int UNIT;
    	try
    	{
    		UNIT = boost::lexical_cast<int>(argv[2]);
    	}
    	catch(const boost::bad_lexical_cast&)
    	{
    		cout << "Usage: input_file.bmp granularity(1..inf)" << endl;
    		exit(EXIT_FAILURE);
    	}
            return UNIT;
    }
    
    ...
       const int UNIT = func();
    ...
    I'm not entirely sure that works, but I think it should.

    HK_MP5 beat me to it...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Good idea, that should work. Thanks!

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Use a const_cast<int>( UNIT )

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by pheres View Post
    Hi,

    do you know any workaround to make the integer UNIT const?
    So, you want to set it initially, and then have it remain const afterward? Sounds like a typical const member of a class. You initialize it in the constructor, but after that, it can't be changed.

    So, you might try wrapping the integer inside a very simple class which holds it as a const. And provide a "operator int()" method to allow it to automatically convert to int where required.

  7. #7
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by cpjust View Post
    Use a const_cast<int>( UNIT )

    the result did surprise me:

    Code:
    	const int UNIT = 0;
    	try
    	{
    		const_cast<int>(UNIT) = boost::lexical_cast<int>(argv[2]);
                    error: invalid use of const_cast with type ‘int’, which is not a pointer, reference, nor a pointer-to-data-member type
                   
    	}
    	catch(const boost::bad_lexical_cast&)
    	{
    		cout << "Usage: input_file.bmp granularity(1..inf)" << endl;
    		exit(EXIT_FAILURE);
    	}
    why is that?

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I don't think you need a class or even a function. Just use two variables and initialize the constant one after you have a valid value for the first one:
    Code:
    	int temp;
    	try
    	{
    		temp = boost::lexical_cast<int>(argv[2]);
    	}
    	catch(const boost::bad_lexical_cast&)
    	{
    		cout << "Usage: input_file.bmp granularity(1..inf)" << endl;
    		exit(EXIT_FAILURE);
    	}
    
    	const int UNIT = temp;

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> why is that?
    Because you need to cast to a reference or you cannot assign to it.
    Code:
    const_cast<int&>(UNIT) = boost::lexical_cast<int>(argv[2]);
    I don't like that idea though, you are promising not to change UNIT, then you change it. It could screw up compiler optimizations or not work altogether.

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Could another possibility be
    Code:
    const int UNIT = boost::lexical_cast<int>(argv[2]);
    And simply catching the exception at a wider scope.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  11. #11
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by Daved View Post
    >> why is that?
    Because you need to cast to a reference or you cannot assign to it.
    Code:
    const_cast<int&>(UNIT) = boost::lexical_cast<int>(argv[2]);
    I don't like that idea though, you are promising not to change UNIT, then you change it. It could screw up compiler optimizations or not work altogether.

    I really started to like that const_cast idea because it utilized minimal code changes. But the compiler seems really confused:

    Code:
    	const int UNIT = 0;
    	try
    	{
    		const_cast<int&>(UNIT) = boost::lexical_cast<int>(argv[2]);
    	}
    	catch(const boost::bad_lexical_cast&)
    	{
    		cout << "Usage: input_file.bmp granularity(1..inf)" << endl;
    		exit(EXIT_FAILURE);
    	}
    gives me a warning "division by zero" on every place I divide by UNIT, so the assignment inside the try block seems not getting recognized by g++.

    So I'll try Daveds solution, it's the shortest an cleanest so far in my eyes. Thanks for all that replys!

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Daved View Post
    I don't think you need a class or even a function. Just use two variables and initialize the constant one after you have a valid value for the first one:
    Well, that only can work if UNIT is only used within that function. If it was a global, for instance, this wouldn't work.

    For that matter, my solution wouldn't work if it needed to be a global. The method I'd use in that case would be to make the wrapper hold the variable as a private member, again using a conversion operator, and make some special function be a friend of the class so that it could set the value.

  13. #13
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by anon View Post
    Could another possibility be
    Code:
    const int UNIT = boost::lexical_cast<int>(argv[2]);
    And simply catching the exception at a wider scope.
    Hm, what is the one step wider scope to that main declares? The global scope. But how can I catch exceptions there? probably I'd have to change the design to utilize that solution

  14. #14
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by pheres View Post
    Hm, what is the one step wider scope to that main declares? The global scope. But how can I catch exceptions there? probably I'd have to change the design to utilize that solution
    Or do something silly like this:

    Code:
    int main()
    {
        try
        {
            return main2();
        }
        catch(...)
        {
        }
        return 1;
    }
    Actually, it's not that silly.

  15. #15
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Is it good style to catch exceptions "far away" from the place there they get thrown?
    (Thats a little off-topic, but it came to my mind after reading your last solution)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 05-13-2007, 08:55 AM
  2. newbie needs help with code
    By compudude86 in forum C Programming
    Replies: 6
    Last Post: 07-23-2006, 08:54 PM
  3. Replies: 14
    Last Post: 06-28-2006, 01:58 AM
  4. Switch/case Problems (long code in post)
    By Wraithan in forum C++ Programming
    Replies: 2
    Last Post: 12-01-2005, 06:40 PM
  5. easy if you know how to use functions...
    By Unregistered in forum C Programming
    Replies: 7
    Last Post: 01-31-2002, 07:34 AM