unrelated code in switch case, no compiler warning/error - c++

I found some very special code and wonder why it compiles. Inside a switch some code is placed not related to any case. See below:
int main()
{
for ( auto i: { 1,2,3,4})
{
switch ( i )
{
case 1:
std::cout << "1" << std::endl;
break;
case 2:
std::cout << "2" << std::endl;
break;
{
std::cout << "What is the sense of this part?" << std::endl;
}
case 3:
std::cout << "3" << std::endl;
break;
default:
std::cout << "default" << std::endl;
break;
}
}
}
gcc (8.3.1) complains only with the warning:
main.cpp: In function 'int main()':
main.cpp:56:81: warning: this statement may fall through [-Wimplicit-fallthrough=]
std::cout << "What is the sense of this part?" << std::end
main.cpp:59:18: note: here
case 3:
clang (7.0.1) did not tell anything, even with -pedantic -Wextra -Wall.
I wonder why both compilers accept that code. The generated executable will never execute it, which is the good thing :-)
Is it legal c++ code?

It is a legal code. You can remove break or put it anywhere in the case.
The break statement, when encountered in statement exits the switch
statement

Related

no instance of overloaded function AddSnapshotListener matches the argument list

i am trying to use Firebase cpp SDK in my win32 application. i used code from documentation
db->Collection("cities")
.WhereEqualTo("state", FieldValue::String("CA"))
.AddSnapshotListener([](const QuerySnapshot& snapshot, Error error) {
if (error == Error::kErrorOk) {
for (const DocumentChange& dc : snapshot.DocumentChanges()) {
switch (dc.type()) {
case DocumentChange::Type::kAdded:
std::cout << "New city: "
<< dc.document().Get("name").string_value() << '\n';
break;
case DocumentChange::Type::kModified:
std::cout << "Modified city: "
<< dc.document().Get("name").string_value() << '\n';
break;
case DocumentChange::Type::kRemoved:
std::cout << "Removed city: "
<< dc.document().Get("name").string_value() << '\n';
break;
}
}
} else {
std::cout << "Listen failed: " << error << '\n';
}
});
from : https://cloud.google.com/firestore/docs/query-data/listen#c++_4
but it gives me following error:
no instance of overloaded function "firebase::firestore::Query::AddSnapshotListener" matches the argument list
is there a way to solve this?
The documentation says the callback for Query::AddSnapshotListener takes 3 arguments, whereas your implementation accepts only two.
The proper signature would be:
.AddSnapshotListener([](const QuerySnapshot& snapshot, Error error, const std::string& error_msg) {
// ...
});
Edit:
The inconsistency between the code in your link and the offical API reference weirded me out a bit, so I dug a bit more. It looks like the third argument was added about 8 months ago, and the user guide just hasn't been update to reflect that yet.
That's really unfortunate.

Call C++ recursive lambda in the same line where it is declared

This is mostly a one liner style type of question, I would normally write this code in multiple lines anyway for readability reasons.
So my question is can I call the recursive lambda in the same statement where it is defined?
So instead of this:
int n=3;
function<void(int)> f {[n,&f](int i){if (i>1) { cout << "func(a, "; f(i-1); cout << ")";} else cout << "a";}};
f(n);
call the function with n in the same line where f is defined.
In one statement which declares several variables ;-)
Mostly not what you want:
std::function<void(int)>
f {[&f](int i){
if (i>1) {
std::cout << "func(a, "; f(i-1); std::cout << ")";}
else
std::cout << "a";
}},
dummy((f(3), nullptr));
Demo
Let me offer a glimpse into the functional programming world, where people usually use combinators to deal with recursive lambdas. There was a proposal (P0200r0) last year to add a simple Y-combinator to the standard library.
Leaving aside the question whether it is a good idea to do this, this would allow you to write and invoke a recursive lambda like this:
y_combinator([](auto self, int i){
if (i>1) {
std::cout << "func(a, ";
self(i-1);
std::cout << ")";
} else {
std::cout << "a";
}
})(6);
The basic idea here is that the y-combinator is a higher order function that wraps a lambda which is passed 'itself' as a first argument. The combinator takes care of wrapping the self argument away for all invocations of the lambda.
You can try it in coliru.
As a matter of fact, you can. Here is a complete example which compiles and runs fine with g++ -std=c++11:
#include <iostream>
#include <functional>
int main() {
std::function<int(int)> f = ([&f](int i){ return i?f(i-1)*i:1; }), trash = (std::cout << f(3) << std::endl, f);
}
However, I don't think it's a good idea to actually use this: The construct , trash = (..., f) would be in order for code golf or obfuscated programming contests, but would not meet my standards for production code.
What you are essentially asking for is to create a temporary instance of std::function and then invoke operator() on that object in the same statement. Both of these fail to compile for me with the same error when I try that:
function<void(int)> f{[&f](int i){ if (i > 1) { cout << "func(a, "; f(i-1); cout << ")"; } else cout << "a"; }}(n);
function<void(int)> f([&f](int i){ if (i > 1) { cout << "func(a, "; f(i-1); cout << ")"; } else cout << "a"; })(n);
error: expected ‘,’ or ‘;’ before ‘(’ token
Pointing at the ( of (n).
See #Jarod42's answer for a viable workaround, if you don't mind the extra variable initialization.
Alternatively, this would work, though it does have to use separate variable declaration and assignment:
function<void(int)> f; f = [&f](int i){ if (i > 1) { cout << "func(a, "; f(i-1); cout << ")"; } else cout << "a"; }, f(n);
Demo
Not sure if you consider it valid since it doesn't use lambda functions, but it is still single line and leaves no temporal variables behind ;)
struct {
struct R {
R(int i) {
if (i>1) { cout << "func(a, "; R(i-1); cout << ")"; }
else cout << "a";
}
} r;
} f{n};

C++ ERROR: Control may reach end of non-void function

Hi I am working on some C++ code in Xcode and I get this error Control may reach end of non-void function. I am also using the Unreal engine standard for code so that is where the FText and int32 comes from. Here is my code:
do {
// get a guess from the player
int32 CurrentTry = BCGame.GetCurrentTry();
std::cout << std::endl;
std::cout << "Try " << CurrentTry << ". Enter your guess: ";
FText Guess = "";
std::getline(std::cin,Guess);
Status = BCGame.CheckGuessValidity(Guess);
switch (Status)
{
case EGuessStatus::Wrong_Length:
std::cout << "Please enter a " << BCGame.GetHiddenWordLength() << " letter word.\n";
break;
case EGuessStatus::Not_Isogram:
std::cout << "Please enter a word without repeating letters.\n";
break;
case EGuessStatus::Not_Lowercase:
std::cout << "Please enter all lowercase letters.\n";
break;
default:
return Guess;
}
} while (Status != EGuessStatus::OK);
}
Please someone help.
You are not showing your complete function, but obviously it is declared to return something; and the default path in the switch also does return Guess.
However, the other three paths in the switch do not return anything, the flow goes behind the switch and there is nothing more. So you have a function that returns nothing, but it needs to return something - just as the message said.

Segmentation Fault with `getopt`

I have a function which handles arguments two three global variables.
It works fine with program -s3, but if I put a space between the s and the argument, I get a segmentation fault even though I'm using atoi to remove whitespace.
Here is the code:
bool handleArgs(int argc, char *argv[])
{
int arg;
bool rtVal = true;
while (true)
{
static struct option long_options[] =
{
{"steps", optional_argument, 0, 's'},
{"walks", optional_argument, 0, 'w'},
{"dimensions", optional_argument, 0, 'd'},
{nullptr, 0, 0, 0}
};
int option_index = 0;
arg = getopt_long (argc, argv, "s::w::d::",long_options, &option_index);
if(arg == -1)
{
break;
}
switch(arg)
{
case 0:
std::cout << long_options[option_index].name << std::endl;
if (optarg)
std::cout << " with arg " << optarg << std::endl;
break;
case 's':
std::cout << "option -s with value " << atoi(optarg) << std::endl;
break;
case 'w':
std::cout << "option -w with value " << atoi(optarg) << std::endl;
break;
case 'd':
std::cout << "option -d with value " << atoi(optarg) << std::endl;
break;
case '?':
/* getopt_long already printed an error message. */
rtVal = false;
break;
default:
rtVal = false;
}
}
return rtVal;
}
In your handler for -s, you don't check for optarg being 0. But you specify two colons after s in your option string: (from man 3 getopt):
Two colons mean an option takes an optional arg; if there is text in the current argv-element (i.e., in the same word as the option name itself, for example, "-oarg"), then it is returned in optarg, otherwise optarg is set to zero. This is a GNU extension.
When the shell starts your program after the invocation program -s 3, it provides three elements in the argv vector:
0: program
1: -s
2: 3
Normally, getopt would interpret this identically to the invocation program -s3, and it's hard to see a reason to change this behaviour. However, gnu helpfully provides you with such an option, allowing you to interpret program -s 3 as a -s option without an argument and a positional argument 3. Once you go down this road, you must check whether optarg is 0 before attempting to use it.
I suspect that you didn't really want to enable this gnu extension. There are very few applications which will benefit from it.

Scope(failure) in C++11?

I wrote a very simple solution however someone laughed and found a flaw as shown here http://ideone.com/IcWMEf
#include <iostream>
#include <ostream>
#include <functional>
#include <exception>
using namespace std;
// Wrong scope(failure)
class FailBlockT
{
typedef function<void()> T;
public:
T t;
FailBlockT(T t)
{
this->t=t;
}
~FailBlockT()
{
if (std::uncaught_exception())
{
t();
}
}
};
struct Test
{
~Test()
{
try
{
FailBlockT f([]()
{
cout << "failure" << endl;
});
// there is no any exception here, but "failure" is printed.
// See output below
}
catch(...)
{
cout << "some exception" << endl;
}
}
};
int main()
{
try
{
Test t;
throw 1;
}
catch(int){}
return 0;
}
In short the problem is my code looks at std::uncaught_exception(). When an exception is thrown and a normal destructor is executed. If i use scope failure there it will look at std::uncaught_exception() and think the object scope is lost due to exception rather then simply walking out of scope.
I can't think of any good solutions to differentiate leaving scope normally VS having an exception thrown IN it. Yes i know throwing is a bad idea in dtors BUT thats why I fail to notice this problem, because I never throw in exceptions.
How do I differentiate/solve this?
No exception was thrown but it thinks it has.
An exception was thrown, just not from right there.
There is no mechanism in C++11 to ask, "Was an exception thrown from code just below me, but not from code elsewhere in the call-stack?" std::uncaught_exception is doing exactly what it is supposed to do: say whether there is an exception currently in the process of being resolved at the time the function is called. And there is, so it returns true.
C++17 adds std::uncaught_exceptions (note the plural), which can be used to detect the difference. With such a tool, you can make your FailBlock object work:
template<typename Func>
class FailBlockT
{
private:
int e_count_;
T t_;
public:
FailBlockT(T t) : e_count_(std::uncaught_exceptions()), t_(t) {}
FailBlock(const FailBlock &) = delete; //The type should not be mobile.
~FailBlockT()
{
if (std::uncaught_exceptions() != e_count_)
{
t_();
}
}
};
std::uncaught_exceptions() returns the number of exceptions that are provoking stack unwinding at the time the call was made. If the number is the same during the constructor and destructor of an object (assuming it's a stack object), then the destructor is not being called due to an exception being thrown through where this type was used.
But without this tool, it, there's not much you can do to differentiate between an exception provoking the exiting of the scope rather than exiting a scope when exception unwinding just happens to be going on. So you're going to have to bite the bullet and catch the exception like everyone else.
Or just don't put this FailBlock thing in destructors. It seems to me that those should go directly into regular functions that can actually throw (and destructors should never throw). It seems to me that you're worried about a corner case that doesn't make any real sense.
I can't think of any good solutions to differentiate leaving scope normally VS having an exception thrown IN it.
Check stack_unwinding library - I have implemented scope(failure) and scope(success) features in C++.
It is based on platform specific function uncaught_exception_count. It is similar to std::uncaught_exception from standard library, but instead of boolean result it returns unsigned int showing current count of uncaught exceptions.
Currently it is tested on {Clang 3.2, GCC 3.4.6, GCC 4.1.2, GCC 4.4.6, GCC 4.4.7, MSVC2005SP1, MSVC2008SP1, MSVC2010SP1, MSVC2012} x {x32, x64}.
In C++11 folowing syntax is available:
try
{
int some_var=1;
cout << "Case #1: stack unwinding" << endl;
scope(exit)
{
cout << "exit " << some_var << endl;
++some_var;
};
scope(failure)
{
cout << "failure " << some_var << endl;
++some_var;
};
scope(success)
{
cout << "success " << some_var << endl;
++some_var;
};
throw 1;
} catch(int){}
{
int some_var=1;
cout << "Case #2: normal exit" << endl;
scope(exit)
{
cout << "exit " << some_var << endl;
++some_var;
};
scope(failure)
{
cout << "failure " << some_var << endl;
++some_var;
};
scope(success)
{
cout << "success " << some_var << endl;
++some_var;
};
}
In C++98 it is a bit more noisier:
try
{
cout << "Case #1: stack unwinding" << endl;
BOOST_SCOPE_EXIT(void) { cout << "exit" << endl; } BOOST_SCOPE_EXIT_END
SCOPE_FAILURE(void) { cout << "failure" << endl; } SCOPE_FAILURE_END
SCOPE_SUCCESS(void) { cout << "success" << endl; } SCOPE_SUCCESS_END
throw 1;
} catch(int){}
{
cout << "Case #2: normal exit" << endl;
BOOST_SCOPE_EXIT(void) { cout << "exit" << endl; } BOOST_SCOPE_EXIT_END
SCOPE_FAILURE(void) { cout << "failure" << endl; } SCOPE_FAILURE_END
SCOPE_SUCCESS(void) { cout << "success" << endl; } SCOPE_SUCCESS_END
}
Also, library has UNWINDING_AWARE_DESTRUCTOR feature. Example:
struct DestructorInClass
{
UNWINDING_AWARE_DESTRUCTOR(DestructorInClass,unwinding)
{
cout << "DestructorInClass, unwinding: "
<< ( unwinding ? "true" : "false" ) << endl;
}
};
However, there are some cases where UNWINDING_AWARE_DESTRUCTOR may give wrong results (though scope(success) and scope(failure) features are not affected by such issues).