throw statement in switch - c++

I try to run a code, but I cannot understand what throw statement do in this part, I thought that we can use ´throw´ statement in try-catch block.
any can help me with this example:
switch(npt) {
case 1: {
a = NPoint1;
b = NLine1;
break;
}
.
.
.
case 5: {
a = NPoint2;
b = NLine2;
break;
}
default:
printf("what you entered is wrong");
throw 1;
};
return 1;
}
thanks in advance for any help

throw is catched by the nearest try-catch block. If it's not in your own code, it's in the code that invoked your's and so on up the stack.

Related

C++ wrap multiple returns

I have the following code which returns ERROR in many lines:
bool func()
{
if (acondition)
{
return 0;
}
return 1;
}
int cmdfun()
{
other_funcs;
if (func()) return ERROR#NUMBER;
other_funcs;
if (func()) return ERROR#NUMBER;
}
But I found its becoming longer and longer. How can I encapsulate return ERROR#NUMBER into func() also? Or any way to encapsulate if (func()) return ERROR; into another independent function?
You can't really achieve this using return on its own.
But you could throw an exception in func which will bubble up the call stack, in the way you seem to want program control to:
struct myexception{}; /*ToDo - inherit from std::exception?*/
bool func()
{
if (acondition){
return 0; /*normal behaviour, perhaps make `func` void if not needed?*/
}
throw myexception();
}
cmdfun then takes the form:
int cmdfun()
{
other_funcs;
func();
other_funcs;
func();
/* don't forget to return something*/
}
Finally, make sure you catch the exception in the caller to cmdfun.
As I said it is not an exception and cannot be handled by std::exception, it is just an error message and ERROR#NUMBER is just another macro. And I cannot access to the caller to cmdfun(). So unable to adopt the first answer. But after asked someone else, it is possible to encapsulate returns and save time when typing them, though it's not recommended, but in this particular case, I can use macro. A complete example is given below:
#include <iostream>
using namespace std;
#define CHECK_VEC(acondition)\
if(checkcondition(acondition)) return -1;
bool checkcondition(bool acondition)
{
if (acondition) return 1;
return 0;
}
int fun_called_by_main()
{
int a = 5 + 4;
bool acondition = a;
CHECK_VEC(acondition);
return 1;
}
int main()
{
int a = fun_called_by_main();
cout << a << endl;
cin.get();
return 0;
}
If I understood corectly your question, you are asking for an 'error reporter' for your own errors. There are 2 solutions for 2 separate cases:
Case 1 - you still want to use a return statement to make an 'error reporter':
To do this, you'll have to make another function or just learn how to use goto. However, you don't need to - your function returns a boolean(bool) - which means you only have 2 possible results: 0 (False) and 1 (True)
bool func()
{
if (acondition)
{
return (bool)0; // False (no error)
}
return (bool)1; // True (error)
// Note: I used (bool)0 and (bool)1 because it is
// more correct because your returning type is bool.
}
void errorcase(bool trueorfalse)
{
switch(trueorfalse)
{
case False:
... // your code (func() returned 0)
break;
default:
... // your code (func() returned 1)
break;
// Note that you will not need to check if an error occurred every time.
}
return;
}
int cmdfun()
{
... // your code
errorcase(func());
... // again - your code
return 0; // I suppouse that you will return 0...
}
But I think that the second case is more interesting (unfortunetly it is also preety hard to understand as a beginner and the first solution might be a lot easier for you):
Case 2 - you decided to do it somehow else - that's by learning throw and catch - I won't repeat the answer because it is already given: #Bathsheba answered preety good...

Switch statement instead of multiple nested if - else?

I've come across a situation where I have a bunch of "systems" that need to be initialized in sequence, with the next system only being initialized if all of the proceeding systems initialized successfully.
This has led me to a whole slew of nested if - else statements. Here's some pseudo-code for visualization.
bool mainInit () {
if (!system1Init ()) {
reportError (); // some error reporting function
}
else {
if (!system2Init ()) {
reportError ();
}
else {
if (!system3Init ()) {
// ... and so on
I find that this starts to look like a mess when you get even a handful of levels to it.
Now I thought of using a switch statement instead, starting at the first case and falling through to the other cases on success, only breaking if there's an error.
bool mainInit () {
switch (1) {
case 1:
if (!system1Init ()) {
reportError ();
break;
}
case 2:
if (!system2Init ())
reportError ();
break;
}
// ....
}
Now, I like this a lot better. I find it much easier to read, especially with some decent comments, but I'm fairly new to programming.
So, my question is: Seeing how this is not how switch statements are traditionally used(at least from what I've seen), is something like this acceptable, or would this be considered bad form?
Being new to programming, I'm trying not to develop too many bad habits that might frustrate and make things more difficult for other programmers down the road.
I did a search, but most of what I found had to do with replacing chains of if - else if statements, not replacing nested ones.
Reference all of the systems in an array, for example an std::vector<mySystem*>, and loop over them sequentially, breaking off on the first fail. This way your entire code is reduced to less than 5 lines of code, even for 500+ systems.
The suggested switch hack is an evil example of XY problem solving: your real problem is that you don't have the array of systems, and are using named variables, thus eliminating all options to more flexibly use all systems, like in a loop.
Assuming that all your system#Init() calls are known at compile time, you can very easily put them in a table and then iterate over that table.
typedef (*system_init)(void);
system_init initialization_functions[] =
{
system1Init,
system2Init,
system3Init,
...
systemNInit
};
bool mainInit()
{
for(size_t idx(0); idx < sizeof(initialization_functions) / sizeof(initialization_functions[0]); ++idx)
{
if(!initialization_functions[idx]())
{
ReportError();
return false;
}
}
return true;
}
However, your existing code looks incorrect since the first mainInit() only calls system1Init() and then exits. Probably not what you wanted in the first place.
if(!system1Init())
{
ReportError();
return false;
}
// if you add an else, the system2Init() does not get called
// even if system1Init() succeeds
if(!system2Init())
{
ReportError();
return false;
}
[...]
return true;
Would the switch answer your problem? Not as it was written. That is, if you wanted to call the mainInit() function with a counter, it could be useful. Drupal uses that mechanism:
bool mainInit(int idx)
{
bool r(true);
switch(idx)
{
case 1:
r = system1Init();
break;
case 2:
r = system2Init();
break;
[...]
}
if(!r)
{
ReportError();
}
return r
}
Note that the table mechanism works the same way as the switch. As long as all the code is found in the systemNInit() functions (and it should be), the switch does not add anything, so you could do something like this too:
bool mainInit(int idx)
{
if(idx < 0 || idx >= sizeof(initialization_functions) / sizeof(initialization_functions[0]))
{
throw std::range_error("index out of bounds");
}
if(!initialization_functions[idx]())
{
ReportError();
return false;
}
return true;
}
Calling the mainInit() with an index can be helpful in case you want to "de-initialize" properly:
int main()
{
for(size_t idx(0); idx < ...; ++idx)
{
if(!mainInit(idx))
{
while(idx > 0)
{
--idx;
mainDeinit(idx);
}
exit(1);
}
}
...app do something here...
}
Use custom exceptions with clear error messages and add a try-catch-report-die around the code in main(). Exceptions are there to specifically make your case look good by making "bad path" implicit.
void initX() { ...; throw std::invalid_argument_exception("..."); }
int main() {
try {
init1(); init2(); ... run();
return 0;
} catch (std::exception const& e) {
log(e.what()); exit 42;
}
}
I'd do it this way:
bool mainInit () {
if (!system1Init ()) {
return(false);
}
if (!system2Init ()) {
return(false);
}
if (!system3Init ()) {
return(false);
}
//...
return(true);
}
//...
if(!mainInit()) {
reportError();
}

C++ Error with operator= of unique_ptr using std::move(nullptr)

I have seen this and I have corrected my code:
int solutionChooser = m_configFile.getChosenSolution();
ISolution* currentSolution;
switch (solutionChooser)
{
case 1:
{
currentSolution = new Solution1());
break;
}
case 2:
{
currentSolution = new Solution2());
break;
}
case 3:
{
currentSolution = new Solution3());
break;
}
case 4:
{
currentSolution = new Solution4());
break;
}
default:
{
std::cout << "The specified solution does not exists\n";
return;
}
}
using unique_ptr as:
int solutionChooser = m_configFile.getChosenSolution();
std::unique_ptr<ISolution> currentSolution;
switch (solutionChooser)
{
case 1:
{
currentSolution.reset(new Solution1());
break;
}
case 2:
{
currentSolution.reset(new Solution2());
break;
}
case 3:
{
currentSolution.reset(new Solution3());
break;
}
case 4:
{
currentSolution.reset(new Solution4());
break;
}
default:
{
currentSolution = std::move(nullptr); // here is the error
std::cout << "The specified solution does not exists\n";
return;
}
}
and now I am getting the error below:
error: no match for ‘operator=’ (operand types are ‘std::unique_ptr<ISolution>’ and ‘std::remove_reference<long int>::type {aka long int}’)
I have ISolution as interface and the SolutionX are classes derived from ISolution
How to fix this? What am I doing wrong?
std::unique_ptr has deleted operator=, that is why you can not use it.
To reset the std::unique_ptr, use reset() method :
currentSolution.reset(nullptr);
but you do not have to do it, since the initial value is nullptr anyway.
Your compiler is wrong, by n3376 std::unique_ptr should have following overloading
unique_ptr& operator=(nullptr_t) noexcept;
so, your code should work fine.
I can't add comments so I'll just post my idea about the answer..
I believe your problem is the copy constructor. The operator = is not defined with unique_ptr so instead you'll have to use a move constructor. I don't remember the correct syntax but it should be something similar to:
/* Header file */
std::unique_ptr<ISolution> currentSolution;
/* CPP file */
std::unique_ptr<ISolution> currentSolution2(new ISolution);
currentSolution = std::move(currentSolution2);
There's probably some mistakes here but hopefully it can get you to the right track. If you want a working example, I got one on floobits, user Simple2012.
Link here: https://floobits.com/Simple2012/Laboration_SearchMethods
Check arr.h and arr.cpp for a concrete example, however I'm using an array there instead of a class, not much difference though.

switch case avoid loop

I have the following code:
int send_cmd( int sock, char * buffer, int lbuffer )
{
int err = 0;
//do_something part 1
while(1)
switch(check_status(buffer)){
case 1:
return 0;
break;
case 0:
if (err > 0)
break;
//do_something part 2
err = 1;
}
return -1;
}
I don't think this is well coded but I didn't know how to optimize it.
I wanna run the "part 2 code" only once and only if "part 1 code" gives an error.
Can you tell me how to make it run correctly? Cause right now doesn't return anything after part 2 is executed once.
I wanna run the "part 2 code" only once and only if "part 1 code" gives an error.
There's no need for a while loop or a switch statement.
// Do something part 1
if (check_status(buffer) == 1) {
return 0;
}
// Do something part 2
if (check_status(buffer) == 1) {
return 0;
}
else {
return -1;
}
If you don't need the loop, you can just use an if and return. Since you don't use err, you can omit it as well.
// first command
int status = check_status(buffer);
if (status == 1)
return 0;
// second command
status = check_status(buffer);
if (status == 1)
return 0;
return -1;
At least in this simple case, switch is not better or faster than if. There might be cases, where this is true, but I won't bet on it. Usually, the optimizer is good enough to emit optimal machine code, whether you use switch or if. So go for the simple, readable and maintainable code.
Looking at your, i think this is what you are trying to achieve using the err variable :
//Part 1
if ( check_status(buffer) ) return 0; //No error
//Part 2
if ( check_status(buffer) ) return 1; //One error
else return -1; //Two errors
You dont need any while loops to do this.

If() vs. switch() - Same meaning but different behaviour?

I would like to transform my if() conditional to switch() from this:
if($configuration['application'][$applicationName]['subdomain'] == true){
foreach($configuration['language'] as $language){
if($language['abbreviation'].'.'.$configuration['application'][$applicationName]['domain'] == $_SERVER['HTTP_HOST']){
$_SESSION['language'] = $language['abbreviation'];
}
}
// If no subdomain detected and redirection is enabled, set default language
if(!isset($_SESSION['language'])){
$_SESSION['language'] = $configuration['application'][$applicationName]['language'];
}
}
else {
$_SESSION['language'] = $configuration['application'][$applicationName]['language'];
}
To this:
switch($configuration['application'][$applicationName]['subdomain']){
case true:
foreach($configuration['language'] as $language){
if($language['abbreviation'].'.'.$configuration['application'][$applicationName]['domain'] == $_SERVER['HTTP_HOST']){
$_SESSION['language'] = $language['abbreviation'];
break;
}
}
default:
$_SESSION['language'] = $configuration['application'][$applicationName]['language'];
break;
}
I think it should be the same but it behaves differently ...
Switch is not working properly ...
I have reformatted your code, please check to make sure it is still correct.
As for your problem, to begin with you are missing a break; statement at the end of your case true: statement. (The break inside the foreach loop simply breaks out of that loop, not the case itself).