это означает, что OP хочет получить ответ, подкрепленный ссылками на стандарт ISO C ++. Не имеет значения, что он компилируется (на самом деле многие нарушения ODR компилируются просто отлично).

отрим этот пример изcppreference:

struct S { static const int x = 1; };
void f() { &S::x; } // discarded-value expression does not odr-use S::x

Я согласен, что&S::x этовыражение отброшенного значенияпоскольку стандарт гласит (9.2, пункт 1 [stmt.expr] изn4700)

Выражения выражения имеют вид

expression-statement:
    expression_opt ;

Выражение является выражением отброшенного значения (раздел 8) ...

Однако этого достаточно дляS::x не бытьУСО используемый? 6.2, пункт 3 [basic.def.odr] гласит

Переменнаяx чье имя появляется как потенциально оцененное выражениеex являетсяУСО используемый поex если

...еслиx это объект,ex является элементом множества потенциальных результатов выраженияeгде либопреобразование lvalue в rvalue (7.1) применяется кe, или жеe является выражением отброшенного значения (раздел 8).

Проблема в том, что выражение отброшенного значения&S::x не имеет потенциальных результатов (что означает, чтоS::x не является потенциальным результатом&S::x), как вы можете видеть из 6.2, параграф 2 [basic.def.odr]:

... Множество потенциальных результатов выраженияe определяется следующим образом:

Еслиe является id-выражением (8.1.4), набор содержит толькоe.Еслиe является подписывающей операцией (8.2.1) с операндом массива, набор содержит потенциальные результаты этого операнда....В противном случае набор пуст.

Тогда, как вы можете объяснить, чтоS::x не используется одр?

 M.M23 дек. 2017 г., 15:50
Другая проблема с формулировкой стандарта заключается в том, чтоS::x это неимя , Это квалифицированный идентификатор. Но очевидно, что предложение «Переменная x, имя которого ...» также должно применяться кx быть квалифицированным идентификатором.
 Ryan Haining28 мар. 2018 г., 22:20
@ М.М как-то так?github.com/cplusplus/draft/pull/1996
 xskxzr31 мая 2018 г., 08:40
@ T.C. Как рационально сделать выражение отброшенного значения&S::x УСО использованиеx?
 T.C.01 июн. 2018 г., 07:07
@xskxzr Получение адреса чего-либо обычно требует, чтобы эта вещь существовала. В чем выгода исключения из этого дела?
 T.C.23 дек. 2017 г., 22:56
Да, это ошибка с нашей стороны. Исправлена.

Ответы на вопрос(3)

&S::x УСО-применениеS::x.

[basic.def.odr]/4

Переменнаяx чье имя появляется как потенциально оцененное выражениеex являетсяУСО используемый поex если только не применить преобразование lvalue в rvalue вx доходностьпостоянное выражение который не вызывает никаких нетривиальных функций и, если x является объектом, ex является элементом набора потенциальных результатов выражения e, где либо преобразование lvalue в rvalue применяется к e, либо e представляет собой выражение отброшенного значения.

Адрес объекта никогда не является константным выражением. Вот почемуS::x используется в одр&S::x.

Чтобы обосновать это последнее утверждение:

[expr.const]/6

Константное выражение - это либо ключевое постоянное выражение glvalue, которое относится к объекту, который является разрешенным результатом постоянного выражения (как определено ниже), либо постоянное основное выражение выражения, значение которого удовлетворяет следующим ограничениям [...]

а также

[expr.const]/2.7

2) выражениеe этовыражение основной константы если оценкаe, следуя правилам абстрактной машины, оценил бы одно из следующих выражений:
[...]
2.7) преобразование lvalue в rvalue, если оно не применяется к

(ни один из следующих пунктов не применяется :)

2.7.1) энергонезависимое glvalue целочисленного или перечислимого типа, которое относится к полному нелетучему const-объекту с предшествующей инициализацией, инициализированной постоянным выражением, или
2.7.2) энергонезависимое glvalue, которое относится к подобъекту строкового литерала, или
2.7.3) энергонезависимое glvalue, которое относится к энергонезависимому объекту, определенному с помощью constexpr, или которое относится к неизменяемому подобъекту такого объекта, или
2.7.4) энергонезависимое glvalue литерального типа, которое относится к энергонезависимому объекту, время жизни которого началось в пределах оценкиe;

 Ben Voigt19 февр. 2019 г., 15:48
&S::x не является lvalue (поэтому он не может подвергаться преобразованию lvalue в rvalue), и& не вызываетS::x пройти преобразование lvalue-в-значение, так почему вы цитируете правила для преобразований lvalue-в-значение?

const int, он может быть полностью отброшен компилятором, если выс помощью его адрес.принятие адрес не достаточно.

Отбрасывание не означает, что значение не вычисляется, это так, но это означает, что нет адреса памяти, содержащего значение const, компилятор просто заменяет переменную const на ее значение, так как это был просто макрос.

Кроме того, если взять указатель на него и извлечь значение из указателя, он не сильно впечатляет компилятор, он просто игнорирует его и использует значение.

Следующий код показывает, что этот код можно скомпилировать и запустить (я тестирую его несколькими компиляторами, я до сих пор не уверен, что он успешно скомпилирован всеми ...), несмотря на тот факт, чтоS::x не было объявлено:

#include <iostream>
using namespace std;
struct S
{
    static const int x=0; 
};
//const int S::x; //discarded
int main()
{
    const int *px = &S::x;  //taking the address
    cout<< *px <<endl; //print the value - OK
    return 0;
}

Но если я попытаюсь использовать сам адрес (не значение), как:

cout<< px <<endl; //print the address - Will be failed

ссылка не удалась: "неопределенная ссылка наS::x».

Поэтому мой вывод таков:брать адрес, не используя его, вообще не считается.

 rustyx11 июн. 2018 г., 17:04
Вопрос был помеченязык-адвокатэто означает, что OP хочет получить ответ, подкрепленный ссылками на стандарт ISO C ++. Не имеет значения, что он компилируется (на самом деле многие нарушения ODR компилируются просто отлично).
Решение Вопроса
 T.C.08 дек. 2018 г., 02:30
Я не собирался писать ответ, чтобы подтвердить то, что я написал в комментариях, но по какой-то причине этот вопрос вызывает много неправильных ответов: |
 b1sub08 дек. 2018 г., 02:31
Я ценю это. Спасибо!

Ваш ответ на вопрос