Почему некоторые непостоянные выражения допускаются в качестве операндов оператора запятой constexpr? - PullRequest
0 голосов
/ 03 декабря 2018

Рассмотрим простой пример:

int foo() {
    return 3;
}

template <int>
struct Bar {};

int a;

int main() {
    int b;
    //Bar<((void)foo(), 1)> bar1;  //case 1. compilation error as expected
    Bar<((void)a, 2)> bar2;        //case 2. no error (long shot but `a' has a linkage so maybe expected)
    Bar<((void)b, 3)> bar3;        //case 3. no error ? (`b' does not have linkage) 
    (void)bar2;
    (void)bar3;
}

Я бы сказал, что это ошибка, но оба последних [clang] и [gcc] принимают кодтак что, может быть, я пропускаю какое-то соответствующее стандартное правило, которое делает код действительным?

1 Ответ

0 голосов
/ 03 декабря 2018

Преобразование lvalue-в-значение не применяется к первому аргументу оператора запятой, если оно не является изменчивым.Следовательно, (void)a, 2 и (void)b, 3 являются константными выражениями.

См. [Expr.comma] / 1

... левое выражение является выражением отбрасываемого значения ...

и [expr] / 12

... Преобразование lvalue-в-значение применяется [к выражению отброшенного значения] тогда и только тогда, когдаВыражение является значением типа volatile-квалифицированного и может быть одним из следующих: ...

...