I like the idea how the short-circuit evaluation works, it can save many unnecessary lines in a code. But I'm not sure how much faith can I place in that it will work with all compilers.
Let consider the following code snippet:
#include <iostream>
#include <string>
#include <cctype>
int main() {
std::string foo { "this is a test" };
auto pos = foo.find_first_not_of("abcdefghijklmnopqrstuvwxyz ");
if(pos != std::string::npos && ispunct(foo.at(pos)))
std::cout << "The first non-alphabetic character is a punctuation.";
else
std::cout << "The string contains only alphabetic characters.";
return (std::cout << std::endl, 0);
}
By the terms of short-circuit evaluation the ispunct(foo.at(pos))
won't be evaluated and the program won't try to access an element out of bounds. Is this approach perfectly safe beyond my GCC 5.4.0 compiler?
Moreover, how about using the short-circuit evaluation outside an if
or a while
statement? Let say I would like to allow null pointers with appropriate safety in the following example:
#include <iostream>
#include <string>
#include <vector>
template<typename... Strings>
std::vector<std::string> pack(Strings... strs) {
using dummy = int[];
std::vector<std::string> out;
(void)dummy { 0, ((void)(strs && (out.push_back({ strs }), false)), 0)... };
return out;
}
int main() {
const auto result = pack("foo", nullptr, nullptr, "bar", nullptr, "baz");
for(const auto& e : result)
std::cout << e << ' ';
return (std::cout << std::endl, 0);
}
The (strs && (out.push_back({ strs }), false))
will emplace the current strs
into the out
vector only if it isn't a nullptr
. I inspected the assembly output of the code above using GCC 5.4.0 and with zero optimization level jump instructions prevent the construction of strings from null pointers. But the question remains the same: is it safe to rely on short-circuit evaluation?