Open Flast opened 6 years ago
This is https://svn.boost.org/trac10/ticket/8298.
@fletchjp said there:
The bug here is that this ever worked. The local variables _a do not provide a true variable. This means that _a = 17 followed by _a = 18 amounts to 17 = 18 i.e. assigning to a constant.
I investigated this and found multiple bugs.
The let
documentation states that _a
should has int
type, but for C++11 it is int const&
because of tr1/decltype result_of differences https://wandbox.org/permlink/27AcBJnXskKPl9uU. If you define BOOST_RESULT_OF_USE_TR1
the example will compile run https://wandbox.org/permlink/Daf4VxdLyETDRs8p.
Internally Phoenix places locals into a vector and than operates on it through const reference, so actually it cannot modify it and passes _a
as int const&
, but mutual operators were working because int const&
was casted to int&
here https://github.com/boostorg/phoenix/blob/5f2061241f528123cc04740294e4811a79138f3a/include/boost/phoenix/scope/detail/local_variable.hpp#L203
The other bug is that let(_a = 0)[_a]()
returns a reference to temporary (with BOOST_RESULT_OF_USE_TR1
even non-const!).
It looks like a disaster, users can use those references to temporaries and do not know this. I have some thoughts about this:
let(_a = 0)[--_a]()
should work.let(_a = 0)[_a]()
) must be a value.let
will start copying const references values (it can be avoided by users with ref
; non-const values will work fine).Nikita
Thank you for tackling this problem. You will see further back down this thread that I wrote before. Some years ago for some time I was attempting to sort out the problems in Phoenix and I did some but not others. After a while I handed the task to others. I am still around and if you find my name in things do ask me what I was doing.
I made some comments on the error handling systems. I never had the power to change the status so some things may not have been documented as closed although I did. Some of my work is documented in a ChangeLog in Phoenix. I don't think it has been used since my efforts.
Best wishes
John Fletcher
From: Nikita Kniazev [notifications@github.com]
Sent: 04 November 2018 18:44
To: boostorg/phoenix
Cc: Fletcher, John P; Mention
Subject: Re: [boostorg/phoenix] phoenix::let
with non-placeholder value can't be modified in c++11 (#69)
I investigated this and found multiple bugs.
The let documentationhttps://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_68_0%2Flibs%2Fphoenix%2Fdoc%2Fhtml%2Fphoenix%2Fmodules%2Fscope%2Flet.html&data=02%7C01%7CJ.P.Fletcher%40aston.ac.uk%7Cc5aa6ca65f5e48e3a85808d642859b9f%7Ca085950c4c2544d5945ab852fa44a221%7C0%7C0%7C636769538939201706&sdata=9wqFdRWLZvQqGJP%2Bp61BL0fXNV7L%2FbguILk4FojyWv4%3D&reserved=0 states that _a should has int type, but for C++11 it is int const& because of tr1/decltype result_of differences https://wandbox.org/permlink/27AcBJnXskKPl9uUhttps://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwandbox.org%2Fpermlink%2F27AcBJnXskKPl9uU&data=02%7C01%7CJ.P.Fletcher%40aston.ac.uk%7Cc5aa6ca65f5e48e3a85808d642859b9f%7Ca085950c4c2544d5945ab852fa44a221%7C0%7C0%7C636769538939201706&sdata=bo2FgVnR4OBpSUJH3yF7q2X%2B%2FjyDBI4sRH%2B%2BlbI%2B8j8%3D&reserved=0. If you define BOOST_RESULT_OF_USE_TR1 the example will compile run https://wandbox.org/permlink/Daf4VxdLyETDRs8phttps://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwandbox.org%2Fpermlink%2FDaf4VxdLyETDRs8p&data=02%7C01%7CJ.P.Fletcher%40aston.ac.uk%7Cc5aa6ca65f5e48e3a85808d642859b9f%7Ca085950c4c2544d5945ab852fa44a221%7C0%7C0%7C636769538939211711&sdata=slwkXqqz9Gkz4fsim0KEa8Zfg03jvLiZrf5VDwbQB5A%3D&reserved=0.
Internally Phoenix places locals into a vector and than operates on it through const reference, so actually it cannot modify it and passes _a as int const&, but mutual operators were working because int const& was casted to int& here buthttps://github.com/boostorg/phoenix/blob/5f2061241f528123cc04740294e4811a79138f3a/include/boost/phoenix/scope/detail/local_variable.hpp#L203
The other bug that let(_a = 0)[_a]() returns a reference to temporary (with BOOST_RESULT_OF_USE_TR1 even non-const!).
It looks like a disaster, users can use those references to temporaries and do not know this. I have some thoughts about this:
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fboostorg%2Fphoenix%2Fissues%2F69%23issuecomment-435694950&data=02%7C01%7CJ.P.Fletcher%40aston.ac.uk%7Cc5aa6ca65f5e48e3a85808d642859b9f%7Ca085950c4c2544d5945ab852fa44a221%7C0%7C0%7C636769538939221721&sdata=OW8bSrxtD3NijxeTs4poIJaI4SvlTsbtJ58kJrf48KA%3D&reserved=0, or mute the threadhttps://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAGG2344Q_BfZ5Loe4mJ1vbQHhnA3Wwiiks5urzWjgaJpZM4VMIV6&data=02%7C01%7CJ.P.Fletcher%40aston.ac.uk%7Cc5aa6ca65f5e48e3a85808d642859b9f%7Ca085950c4c2544d5945ab852fa44a221%7C0%7C0%7C636769538939221721&sdata=94foUisKpwUeHUFbw%2Bu5b2DHMG94HYOHfPE26HmFwSI%3D&reserved=0.
Following code doesn't compile in C++11, but C++03 does.