Edit report at http://bugs.php.net/bug.php?id=52825&edit=1
ID: 52825 User updated by: mbroxer at post dot ru Reported by: mbroxer at post dot ru Summary: return by reference with ternary operator causes notice "Only variable..." Status: Bogus Type: Bug Package: *General Issues Operating System: Windows XP SP3 PHP Version: 5.3.3 Block user comment: N New Comment: Thank you for pointing me to that article, it's strangely placed in the chapter on Comparison operators, which Conditional operator isn't, so I haven't found it in the first place. Well, although C does have pointers, what I meant was C++, which has references and ternary operator works with them. This code is perfectly valid and outputs 20, as expected: #include <iostream> using namespace std; class test { public: int i, j; test():i(8),j(10){} int& a(int b) { return b == 2 ? i : j; } }; int main() { test my; int& a = my.a(2); a += 12; cout << "Weekly Hours: " << my.a(2) << endl; return 0; } So, I still find it hard to follow the PHP logic in this. "the ternary operator is a statement, and that it doesn't evaluate to a variable, but to the result of a statement." -- but result of a statement is a variable. I suppose this has to do with some PHP internal specifics, which I am not aware of. But if this use of ternary operator doesn't work and produces a wrong result, then surely it should be a warning, not a notice. But in any case, thank you again for your feedback, I'm mostly writing this comment for people who might research this subject in the future, maybe deciding to improve things, and I've no intentions to offend anyone in any way. Previous Comments: ------------------------------------------------------------------------ [2010-09-13 12:49:00] cataphr...@php.net return $key > 0 ? $this->a[$key] : $this->b[$key]; is the same as return ($key > 0 ? $this->a[$key] : $this->b[$key]); C is not comparable because it has only pass and return by value. This is documented in http://pt.php.net/ternary : Note: Please note that the ternary operator is a statement, and that it doesn't evaluate to a variable, but to the result of a statement. This is important to know if you want to return a variable by reference. The statement return $var == 42 ? $a : $b; in a return-by-reference function will therefore not work and a warning is issued in later PHP versions. See also http://stackoverflow.com/questions/3389928/can-you-pass-by-reference-while-using-the-ternary-operator/3390182#3390182 ------------------------------------------------------------------------ [2010-09-13 06:46:55] mbroxer at post dot ru I'm sorry, the expected result and actual result got mixed up when I was submitting. Expected is actual, and actual is expected. ------------------------------------------------------------------------ [2010-09-13 06:45:41] mbroxer at post dot ru Description: ------------ I don't know if it's a bug, or that's how it should be, but it would be logical to assume that a ternary operator is equal to an IF block: return $a ? $b : $c; // == if ($a) return $b; else return $c; I believe that's how it is in C. However when returning a reference, the first version produces a notice: "Notice: Only variable references should be returned by reference" It's hard to tell if this is normal behaviour or not, but it's confusing. If this is normal functionality, then I think this should be in documentation, at least in a form of a comment. Test script: --------------- class test { private $a = array(); private $b = array(); function &getA($key) { return $key > 0 ? $this->a[$key] : $this->b[$key]; // the following line gives no notice // if ($key > 0) return $this->a[$key]; else return $this->b[$key]; } } $a = new test; $b = &$a->getA('1'); Expected result: ---------------- Notice: Undefined index: 1 in - on line 9 Notice: Only variable references should be returned by reference in - on line 9 Actual result: -------------- Notice: Undefined index: 1 in - on line 9 ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=52825&edit=1