1

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?

Akira
  • 4,385
  • 3
  • 24
  • 46
  • 1
    The duplicate doesn't seem to cover short-circuiting a parameter pack – M.M Jun 15 '17 at 00:01
  • 1
    Of course it is safe. That's an integral part of the definition of the && and || operator,in both C and C++. They are also guaranteed to be evaluated in order. It is even considered good practice to rely on them. – Michaël Roy Jun 15 '17 at 14:57
  • 1
    When mixing several && and || in a test condition, make sure you use parenthesis in the appropriate place, as && has precedence over ||. which can make reading such test conditions a nightmare. You can check the precedence of operators here http://en.cppreference.com/w/c/language/operator_precedence, but nothing beats parenthesis for readability.. – Michaël Roy Jun 15 '17 at 15:04

0 Answers0