Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

rhag posted:

But if the business rules change so that the input is invalid for some other reason (mars, earth and the sun are in alignment for example) then throwing out_of_range is kinda ... wrong, isn't it? The input is invalid. Why? Why do you care? It's invalid and that's that.
The obvious case is that you want to show different error messages for different problems, and having the error message controlled by the UI rather than the layer throwing the error. It's much easier to throw away excess detail about what exactly went wrong than to go the other direction. Wanting all of your validation exceptions to have a common base class to simplify that would be a good reason for mapping std::out_of_range to a different exception type, but I don't have any idea what that has to do with the idea that throwing std::out_of_range is using exceptions for control flow and throwing some other exception is not.

rhag posted:

Then again, probably in most real world cases this may not matter, no matter what you throw out (if anything, just returning may be just fine). Of course, in cases where good design practices have a performance penalty ... then screw good design. But usually, it pays in the long run.
I was referring to code quality pessimization, not performance. If one exception is fast enough, two probably is as well.

Adbot
ADBOT LOVES YOU

Volguus
Mar 3, 2009

Plorkyeran posted:

The obvious case is that you want to show different error messages for different problems, and having the error message controlled by the UI rather than the layer throwing the error. It's much easier to throw away excess detail about what exactly went wrong than to go the other direction. Wanting all of your validation exceptions to have a common base class to simplify that would be a good reason for mapping std::out_of_range to a different exception type, but I don't have any idea what that has to do with the idea that throwing std::out_of_range is using exceptions for control flow and throwing some other exception is not.

It all has to do with how it's handled. Throwing out_of_range from your function exposes an implementation detail (may or may not be ok, usually is not). Throwing exception within a try and catching it later (rethrowing it or just returning doesnt matter) it is just a simple control flow problem. Why? You can use a simple return if you want to exit the function cleanly. You can use a boolean variable if you want to check for success later. You have 100 other mechanisms available to accomplish the same thing without going into exceptions.
There are quite a few examples given at http://c2.com/cgi/wiki?DontUseExceptionsForFlowControl .
However, in C++ land, one must be worried about performance as well: https://www.youtube.com/watch?v=N9bR0ztmmEQ.

The links provided hopefully can explain better than I can. If not, don't worry, for most cases it's probably not a huge issue.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I feel like this argument is kind of going over my head. I don't really understand the whole discussion about passing information about failure back to the caller. As I said to astr0man on the previous page, the point of the function in which the relevant code appeared (at least, the point of the function as I originally intended it) was that it would test the user's input, decide whether it was valid, and either display a "friendly" error message explaining what was wrong (if it was not valid) or execute the requested operation by delegating to other functions (it it was valid). By design, the main loop of the program doesn't need to know which of those it was. It just repeatedly delivers lines of input to this function, it doesn't care what they mean or whether they worked.

code:
Main loop in main(): "while (!menuHandler.IsQuitting()) {/* do stuff */}"
         |
         |
         |
         v
Input parse method (where the code in question appears)
         |
         |
         |
         v
 Further functions

Volguus
Mar 3, 2009

Hammerite posted:

I feel like this argument is kind of going over my head. I don't really understand the whole discussion about passing information about failure back to the caller. As I said to astr0man on the previous page, the point of the function in which the relevant code appeared (at least, the point of the function as I originally intended it) was that it would test the user's input, decide whether it was valid, and either display a "friendly" error message explaining what was wrong (if it was not valid) or execute the requested operation by delegating to other functions (it it was valid). By design, the main loop of the program doesn't need to know which of those it was. It just repeatedly delivers lines of input to this function, it doesn't care what they mean or whether they worked.

code:
Main loop in main(): "while (!menuHandler.IsQuitting()) {/* do stuff */}"
         |
         |
         |
         v
Input parse method (where the code in question appears)
         |
         |
         |
         v
 Further functions

In which case then, a simple return from the if statement would do, just like you're doing from the catch.

ExcessBLarg!
Sep 1, 2001
Bikesheds are awesome.

rhag posted:

You were using exception for control flow. Don't do that. It is a well known anti-pattern. Exceptions should be used for exceptional situations, not to break from a loop.
He's not using an exception for control flow though. Exceeding maxAllowedValue is genuinely an exceptional situation that's not intended during normal program operation with correct business-appropriate inputs. It just happens that the exception is (can be) thrown in the same function as it's caught.

So, I would agree with:

If that's the only exceptional case, immediately following the maxAllowedvalue check with "cout; return" is the simplest error handling approach.

If there were multiple points at which the exception can be thrown in that function, then using exceptions is no better than using goto. However, it's also no worse. In some circumstances I'd probably use gotos, but if exceptions are extensively elsewhere in the code base, I'd use exceptions for confirmity. This is one of the interesting parts of C++ too, as most languages support only goto (C), exceptions (Java), but not both. Thus, the choice is something unique to C++.

If the exception handler already exists in that function to catch exceptions deeper in the call stack, it's quite reasonable to add a throw for a "local error" (violation of business rule) to reuse the same exception handler. This also has the benefit that, if the code block implementing the business rule validation gets refactored to some function deeper in the call stack, the exception still works the same.

Anyways, what folks are really going after is that, the power of exceptions lies in being able to handle them one of two places: (i) where an exceptional event can reasonably be recovered (e.g., restarting a request), or (ii) at the top of the call stack where a general handler can log the exception and provide the appropriate user-visible error.

ExcessBLarg! fucked around with this message at 16:47 on Jun 7, 2014

Vanadium
Jan 8, 2005

This is why exceptions are terrible~

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Vanadium posted:

This is why exceptions are terrible~

longjmp or go home.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
The main thing is that the point of exceptions is to propagate the error for you. It's mainly for cases where a single operation consists of many smaller operations that can cause the entire thing to fail.

An example would be that at one point, I had some code that was supposed to parse a file format. One of the things that could happen while parsing is that something would request more data than could be read from the file, which was an unrecoverable error. The way it was implemented was that the "ReadBytes" function would throw an exception if it got less than it requested, but everything else in the parser could be written as if ReadBytes always succeeded. If it failed, then the stack unwind would release all of the partially-loaded data, and I only had to worry about catching it at the point where that stops being a critical error (i.e. usually where "ParseResourceFile" was called). Without exceptions, doing something like that is a lot more cumbersome because almost every function would have to be checking for error conditions at almost every function call, and bail out with an error of its own if that failed.

It doesn't make a lot of sense to use them when the throw and catch are in the same function, because in that case, you can go to the error handler using much cheaper constructs like break and goto. It would make more sense if, for example, you had something like a "RangeParseInt" function used in many places which would throw an out of range exception and needed to fail a larger operation if that happened.

OneEightHundred fucked around with this message at 17:33 on Jun 7, 2014

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

Hammerite posted:

An earlier version of the method did something like this:

code:
bool tooBig = false;
try
{
    inputInt = std::stoi(input); // not strtoi()!!!
}
catch (std::out_of_range)
{
    tooBig = true;
}
if (inputInt > maxAllowedValue)
{
    tooBig = true;
}
if (tooBig)
{
    cout << "That number is too big!" << endl;
    return;
}
until I looked at it and thought, "screw it, I can test both things in the same place and unify what happens when the number is too big". That's when I moved the test inside the try block and added the throw statement. It meant I could get rid of the boolean flag variable.

I would probably rewrite that to something like
code:
try
{
    inputInt = std::stoi(input);
    if (inputInt <= maxAllowedValue)
    {
        // Valid input
        return;
    }
}
catch (std::out_of_range)
{
    // Error, handled below.
}

cout << "That number is too big!" << endl;
return;

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Zopotantor posted:

I would probably rewrite that to something like
code:
try
{
    inputInt = std::stoi(input);
    if (inputInt <= maxAllowedValue)
    {
        // Valid input
        return;
    }
}
catch (std::out_of_range)
{
    // Error, handled below.
}

cout << "That number is too big!" << endl;
return;

So you're saying to handle the case where the input is valid inside the try; so where "// Valid input" appears is where the function takes the requested action by calling further functions. OK, but (1) what if something unrelated lower down throws std::out_of_range and it gets caught by that catch block? The user will see an error message stating incorrectly that they entered a number that is too big. (2) if the function checks for multiple types of error conditions, aren't you setting yourself up to write code that looks like this:

code:
if (condition_1_is_okay)
{
    if (condition_2_is_okay)
    {
        if (condition_3_is_okay)
        {
            if (condition_4_is_okay)
            {
                // ...
            }
        }
    }
}

qntm
Jun 17, 2009
What is the purpose of this code?

C++ code:
try {

    // some code goes here

} catch (...) {
    throw;
}
I haven't omitted any catch blocks. Isn't this just equivalent to

C++ code:
// some code goes here
?

Gazpacho
Jun 18, 2004

by Fluffdaddy
Slippery Tilde
One lets you debug the exception and the other doesn't.

Star War Sex Parrot
Oct 2, 2003

I'm fairly certain that if whatever is in the try block generates an exception, execution will enter the catch, do some stuff, and then pass the same exception. In theory I think it's a way to do something when an exception is thrown while leaving the actual handling to another point in the program.

qntm
Jun 17, 2009
I also haven't omitted any code inside the catch block, in case that's not clear. There's no "do some stuff" in there, it just rethrows.

Marta Velasquez
Mar 9, 2013

Good thing I was feeling suicidal this morning...
Fallen Rib

qntm posted:

I also haven't omitted any code inside the catch block, in case that's not clear. There's no "do some stuff" in there, it just rethrows.

Maybe there a debugging breakpoint set on the throw? I guess that would let you see some of the exception's context before it goes up to the handler.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
It does guarantee that the stack will be unwound to at least this point before the program terminates, even if there are no handlers further up the stack. Yay, C++.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

rjmccall posted:

It does guarantee that the stack will be unwound to at least this point before the program terminates, even if there are no handlers further up the stack. Yay, C++.

This would be observable by which destructors run, I guess?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Subjunctive posted:

This would be observable by which destructors run, I guess?

Yes. Whether a stack with no handlers is unwound is implementation-defined, but a catch is a handler, even if it obviously immediately rethrows.

Paul MaudDib
May 3, 2006

TEAM NVIDIA:
FORUM POLICE
Anyone know of a book/website/etc with basically a "MPI Cookbook" or "MPI Gems" or something along those lines?

I did some MPI coding back in school, so I understand the basic principles of distributed memory/message passing but it was a long time ago, the class was run by a professor who didn't really give a poo poo, and I had problems with synchronization in some of the more complex cases. I'm going to be doing some MPI stuff again and I'd like some better references to use if anyone knows any that are worthwhile.

I feel a bit dumb asking this, but is there a good way to do parallel debugging of the MPI parts of my code? It was a raw UNIX environment and were never taught more than debugging using per-node log-file outputs, which isn't really a very productive or scalable way to work. I have access to that Unix cluster as well as whatever I can rig with a couple Windows machines with the MS-MPI package or Cygwin or whatever.

Paul MaudDib fucked around with this message at 20:59 on Jun 11, 2014

That Turkey Story
Mar 30, 2003

rjmccall posted:

It does guarantee that the stack will be unwound to at least this point before the program terminates, even if there are no handlers further up the stack. Yay, C++.

This. It's also one of the reasons why you shouldn't be doing it in most applications. Use destructors instead of catch all/rethrow. If you really want to do something only when an exception is thrown and not when normally leaving scope, then you can use std::uncaught_exception in a destructor body. If exceptions were always thrown only on post-condition failures as opposed to [improperly] on precondition failures (I.E. standard "logic" errors :rolleyes:) then this wouldn't be as important, but that is not the world we live in.

Dren
Jan 5, 2001

Pillbug
is >> to close a nested template not an error anymore?

hooah
Feb 6, 2006
WTF?

Dren posted:

is >> to close a nested template not an error anymore?

Not if you're using C++11, I believe, no.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
And in practice all compilers had supported it for quite a while pre-C++11, although some non-compiler tools may barf on it.

High Protein
Jul 12, 2009
Suppose I have some template function
code:
template <class T>
void DoSomething(T& bla)
{
 SetSomePointer(&bla);
}
Is there a way to use 'bla' instead of '&bla' as SetSomePointer's parameter when T is a pointer? I tried using std::is_pointer<T>::value ? bla : &bla but no dice, at least not on my compiler.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
C++ code:
template <typename T>
void DoSomething(T& bla) { SetSomePointer(&bla); }

template <typename T>
void DoSomething(T* bla) { SetSomePointer(bla); }

High Protein
Jul 12, 2009
Thanks, I was hoping there was some trick similar to std::cref but specialization'll have to do :)

shrughes
Oct 11, 2008

(call/cc call/cc)

High Protein posted:

Is there a way to use 'bla' instead of '&bla' as SetSomePointer's parameter when T is a pointer? I tried using std::is_pointer<T>::value ? bla : &bla but no dice, at least not on my compiler.

Do you really want to do that? It sounds like you're making a coding horror.

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

High Protein posted:

Suppose I have some template function
code:

template <class T>
void DoSomething(T& bla)
{
 SetSomePointer(&bla);
}

Is there a way to use 'bla' instead of '&bla' as SetSomePointer's parameter when T is a pointer? I tried using std::is_pointer<T>::value ? bla : &bla but no dice, at least not on my compiler.

Yes check in type_traits ; remove_pointer should do

High Protein
Jul 12, 2009

shrughes posted:

Do you really want to do that? It sounds like you're making a coding horror.

I'm must just experimenting :)

Malcolm XML posted:

Yes check in type_traits ; remove_pointer should do

How should I use that? The issue is that I'm not manipulating a type, but a variable.

Sauer
Sep 13, 2005

Socialize Everything!

High Protein posted:

How should I use that? The issue is that I'm not manipulating a type, but a variable.

Those are the same thing. Variables are types.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

DSauer posted:

Those are the same thing. Variables are types.
In a sense that is true, but remove_pointer is still not applicable to what he's doing.

Xeom
Mar 16, 2007
Teaching myself some cpp, quick question.
C++ code:
auto numaddv = *numlist.cbegin();
	for (auto i = numlist.cbegin(); i != numlist.cend(); i++){
		if (i != numlist.cend() && i !=numlist.cbegin()){
			numdisp.push_back(*i + numaddv);
			numaddv = *i;
		}
	}
Where numlist and numdisp are just integer vectors. Is there a way to do this without the numaddv variable? In other words is there a way to tell the iterator to just go front or back for a single addition manipulation?

Obvious way the doesn't work is numdisp.push_back(*i + *(i+1));. Just to communicate the basic idea of what I want to do.

Xeom fucked around with this message at 23:40 on Jun 14, 2014

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
C++ code:
for (auto i = numlist.cbegin(); i != numlist.cend() && i + 1 != numlist.cend(); ++i) {
	numdisp.push_back(*i + *(i + 1));
}
works for std::vector. For containers without random-access iterators (such as std::list), you can use std::next:
C++ code:
for (auto i = numlist.cbegin(); i != numlist.cend() && std::next(i) != numlist.cend(); ++i) {
	numdisp.push_back(*i + *std::next(i));
}

Xeom
Mar 16, 2007

Thank you, I knew there must be a better way. I've only gotten as far as iterators for vectors and strings so far (Chapter 3 of c++ primer).

Xeom fucked around with this message at 00:03 on Jun 15, 2014

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.
Hello again thread!

I've got a dialog with two slider controls (CSliderCtrl). Both sliders range from 0-100, but SliderA's value must always be higher than SliderB's value. The CSliderCtrl class passes the event of their manipulation through the parent window's OnHScroll event, so SliderA and SliderB share the same event handling code.

I'm currently comparing the positions of each slider against the previously held value in order to check which one is being manipulated by the user (so then the other one must be adjusted in case the A > B constraint is violated), but I'm curious: is there any way to explicitly check which control has fired the event?

High Protein
Jul 12, 2009

Newf posted:

Hello again thread!

I've got a dialog with two slider controls (CSliderCtrl). Both sliders range from 0-100, but SliderA's value must always be higher than SliderB's value. The CSliderCtrl class passes the event of their manipulation through the parent window's OnHScroll event, so SliderA and SliderB share the same event handling code.

I'm currently comparing the positions of each slider against the previously held value in order to check which one is being manipulated by the user (so then the other one must be adjusted in case the A > B constraint is violated), but I'm curious: is there any way to explicitly check which control has fired the event?
It says right on MSDN that one of the OnHScroll parameters is a pointer to the control that fired the event: http://msdn.microsoft.com/en-us/library/e14hhbe6.aspx. You can also use ON_HSCROLL_REFLECT and create your own custom slider control that handles the message, instead of it being caught by the window.

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.
Haha. Well nuts to me. Thanks.

Xeom
Mar 16, 2007
Is there something you have to do to enable the use of constexpr?
I have a simple line.
constexpr int size = 5;

VS2013 is giving me the error C2065: 'constexpr' : undeclared identifier. Const seems to work fine, but not constexpr.

The Laplace Demon
Jul 23, 2009

"Oh dear! Oh dear! Heisenberg is a douche!"

Xeom posted:

Is there something you have to do to enable the use of constexpr?
I have a simple line.
constexpr int size = 5;

VS2013 is giving me the error C2065: 'constexpr' : undeclared identifier. Const seems to work fine, but not constexpr.

Install the first CTP. See here: http://blogs.msdn.com/b/vcblog/archive/2013/12/02/c-11-14-core-language-features-in-vs-2013-and-the-nov-2013-ctp.aspx

There's another with linker improvements here.

The Laplace Demon fucked around with this message at 19:17 on Jun 28, 2014

Adbot
ADBOT LOVES YOU

Xeom
Mar 16, 2007

Edit: Babies first reading.(that's in reference to myself).

Xeom fucked around with this message at 20:46 on Jun 28, 2014

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply