Является ли реализация разрешена для размещения двух идентичных определений функций по одному и тому же адресу или нет?
В стандарте С++ говорится о операторе равенства ==
:
[C++11: 5.10/1]:
[..] Два указателя одного типа сравнивают одинаковые, если и только если оба они равны нулю, оба указывают на одну и ту же функцию или оба представляют один и тот же адрес.
Моя первоначальная интерпретация заключалась в том, что функции не имеют семантически "адреса" как таковые на этом уровне, и поэтому "или оба представляют один и тот же адрес" могут быть предназначены только для обозначения объектов, а не функций. В противном случае зачем беспокоиться о статье "указать на ту же функцию"?
То есть, два указателя функций одного и того же типа сравниваются одинаково, если и только если обе указывают на одну и ту же функцию, период.
Следствием этого было бы то, что поведение, описанное в этом вопросе (указатели на две разные, но идентичные функции имеют одинаковые значения), будет ошибкой реализации, поскольку указатели для отдельных функций потребуется быть уникальным.
Я чувствую, что это цель предложения, но я не могу найти способ объективно защитить точку зрения, что именно так следует понимать значение прохода, или что это действительно было целью комитета, и теперь моя интерпретация поставила под вопрос:
[D] ссылается на меня, как "[...] или оба представляют один и тот же адрес". не удовлетворяет поведению Visual С++. (@jstine)
Поэтому мой вопрос касается намерения этого стандартного отрывка.
Или:
-
Я нахожусь на правильном пути: указатели на функции должны сравниваться, если они оба указывают на одну и ту же функцию ( "адреса" будут прокляты) или
-
В проходе есть избыточность: указатели на функцию должны сравнивать одинаковые, если оба они указывают на одну и ту же функцию или оба представляют один и тот же адрес; и, в свою очередь, реализации разрешено создавать две функции по одному и тому же адресу.
Что это?
Ответы
Ответ 1
Хорошо, посмотрите на выражение логически. У вас есть три условия:
К этим предложениям присоединяется логическое "или". Поэтому, если любое из них истинно, то двум указателям разрешено сравнивать одинаковые. Если компилятор так решает, можно пропустить # 3, но все же пройти # 2. Логический "или" означает, что такие указатели будут сравнивать равные.
Кроме того, следует отметить, что указатели элементов не имеют "адреса" в традиционном смысле. Они имеют значение, но это не адрес памяти. Вот почему вам не разрешено отправлять их на void*
и т.д.
Проход гарантирует, если заданы указатели на функции t
и u
, если t == u
, то t(...);
приведет к такому же поведению, что и u(...);
. Это поведение будет либо ссылаться на NULL, вызывать одну и ту же функцию, либо выполнять код по тому же адресу. Таким образом, такое же поведение было.
Технически, проблема Mehrdad заключается в том, что он получает одинаковое значение от двух разных имен функций-членов. Так что # 3 применяется. Я не вижу ничего в стандарте, который требует, чтобы разные имена функций-членов возвращали разные значения при получении функций для них.