Home > Net >  What differs between parentheses and curly in std::tuple?
What differs between parentheses and curly in std::tuple?

Time:10-18

Well today I met a werid behavior when using std::tuple() and std::tuple{}.

Here is an easy demo:

#include <iostream>
#include <tuple>

#define   rd   ({ int       x = (std::cin >> x, x); x; })

template <typename... Args>
void log(const Args &...args) { ((::std::cout << args << ", "), ...); }

auto main() -> int {

    auto [a, b] = std::tuple(rd, rd);
    auto [c, d] = std::tuple{rd, rd};

    log(a, b, c, d);

    return {};
}

Run:

 echo '1 2 3 4' > input
 clang   -std=c  17 demon.cpp
 ./a.out < input
 g   -std=c  17 demon.cpp
 ./a.out < input
 cat demon.cpp

And I got 2 different results: 1, 2, 3, 4 and 2, 1, 3, 4. That's out of my expectation. I turned to my friends and got the reply of "The macro rd is a unspecific behaivor". However, I am still confused with this answer after learning something about unspecific behaivor.

CodePudding user response:

Your friends are correct.

The unspecified behaviour occurs because the evaluation order of function arguments is not specified, it can happen in any order and can change between calls. Meaning the order of std::cin is not guaranteed. The compiler is free to reorder them as it sees fit. This applies to std::tuple(), hence the incorrect output.

On the other hand for braced-init-list, the order is fixed left-to-right, therefore std::tuple{} is safe and the output is guaranteed.

Furthermore, in rd, having braced-statements in expressions is not standard C so you are at the mercy of your compiler. I would seriously recommend macro-less refactoring, hiding std::cin in an expression seems like asking for trouble.

Why not simple read_int() function or generic read_T? Then you can generalize to read_Ts<T1,T2,T3...> with explicit sequencing. For example:

template<typename T>
T read_T(){
    T x;
    std::cin>> x;
    return x;
}

template<typename...T>
auto read_Ts(){
    return std::tuple{read_T<T>()...};
}
  •  Tags:  
  • c
  • Related