Почему Perl 5.14 использует определение (0+GvGP(gv)->gp_cv) для GvGC?

Я провожу какое-то исследование, связанное с совместимостью mod_perl-Apache-Perl. Недавно я попытался собрать mod_perl 2.0.4, используя Perl 5.14.2. Фаза компиляции была преждевременно прервана с ошибкой:

modperl_perl.c: In function ‘modperl_perl_core_global_init’:
modperl_perl.c:58:9: error: lvalue required as left operand of assignment

В этом месте прописан следующий код:

    GvCV(gv) = get_cv(cglobals->sub_name, TRUE);

В поисках того, что могло вызвать эту ошибку, я нашел разницу между предыдущими версиями Perl и Perl 5.14 (CORE/gv.h):

    #define GvCV(gv) (GvGP(gv)->gp_cv)   /* previous versions */

vs

    #define GvCV(gv) (0+GvGP(gv)->gp_cv)  /* in Perl 5.14 */

Удаление этого 0+ из определения позволяет успешно скомпилировать mod_perl 2.0.4, и это нормально, поскольку 0+... не распознается как lvalue по сравнению с предыдущими версиями.

Почему в определении GvCV используется 0+ и нужно ли это? или безопасно удалить его и получить определение GvCV(gv), как в предыдущих версиях Perl?


person ArtM    schedule 12.05.2012    source источник


Ответы (1)


Коммит, вызвавший это изменение, называется этим. .

Краткий журнал:

добавить макросы GvCV_set() и GvGP_set().

и сделать GvCV() и GvGP() только значением.

Это сделано для того, чтобы будущая фиксация позволила устранить некоторую магию обратной ссылки между GV и CV, что потребует полного контроля над назначением слота gp_cv.

Таким образом, цель этого 0+ как раз и состоит в том, чтобы сделать эти макросы rvalues. Вам лучше подождать, пока mod_perl обновит свой код, чтобы он соответствовал новой семантике, потому что возврат этих макросов в какой-то момент будет недействительным. (Я не знаю, реализован ли этот будущий коммит или нет.)

Связанное обсуждение: http://www.nntp.perl.org/group/perl.perl5.porters/2011/01/msg167682.html

person Mat    schedule 12.05.2012
comment
Таким образом, этот префикс 0+ добавлен, чтобы исключить любое использование CV в качестве lvalues и заставить разработчиков использовать вместо него GvCV_set(). И удалять этот префикс 0+ небезопасно. Я правильно понял? о mod_perl: более новые версии успешно компилируются с Perl 5.14 (только что посмотрел, там используется GvCV_set()); 2.0.4 старая. Я думаю, что ваш ответ достаточно близок к тому, что я ожидал. Спасибо. - person ArtM; 12.05.2012
comment
Да, вот как понять вещи. - person Mat; 12.05.2012
comment
@ArtM, да, именно так. - person ikegami; 12.05.2012