- What was the reasoning behind &'s syntax? - 19 Updates
- mixing compilers (g++ but Intel others)? - 1 Update
- Cancel "Re: What was the reasoning behind &'s syntax?" - 3 Updates
- std::find() with easier interface - 2 Updates
"Öö Tiib" <ootiib@hot.ee>: May 03 03:49PM -0700 On Tuesday, 3 May 2016 22:43:41 UTC+3, Rick C. Hodgin wrote: > > Error here: 'x' is passing to inbuilt operator++ just by value in your > > theory so it should be '++@x;'. > No. Usage within the function would be normal syntax. Woosh. How can you call any functions or operators outside of a function? > However, if you wanted to pass it again by reference, then you could > use @x. Otherwise it would be driven by the called function. [confused] That 'x' is passed by reference to operator++, operator++ modifies its value. |
Geoff <geoff@invalid.invalid>: May 03 04:48PM -0700 On Tue, 3 May 2016 10:26:22 -0700 (PDT), "Rick C. Hodgin" >> pass or use the reference. >I WANT to use special syntax to pass by reference. I want it to show up >in source code so I know it's a reference rather than a value pass. Then you should abandon C++ and take up C#. :-D It has the ref keyword and function declarations, definitions and calls must all have the ref keyword in order for it to compile. In the IDE, Intellisense gives you the information as you type and shows you the error list even before you compile. C++ could have easily used a new keyword for this instead of overloading & for it but apparently this was introduced before C++ was 'not C'. |
Jorgen Grahn <grahn+nntp@snipabacken.se>: May 04 01:03AM On Tue, 2016-05-03, Chris Vine wrote: >> little syntactic twist. That really does aid understanding, >> particularly if your function names don't help. > A little, but in an era of multiple processors not much. Nitpick: having multiple processors doesn't mean you /have/ to use threads, or use threads in such a way that you can have data races anywhere in the code. [snip] /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Jerry Stuckle <jstucklex@attglobal.net>: May 03 09:09PM -0400 On 5/3/2016 1:26 PM, Rick C. Hodgin wrote: > in source code so I know it's a reference rather than a value pass. > Best regards, > Rick C. Hodgin That's not how references work, Rick. The whole purpose is to *make them transparent*. If you want to use "special syntax", use pointers. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 07:17PM -0700 On Tuesday, May 3, 2016 at 7:48:58 PM UTC-4, Geoff wrote: > C++ could have easily used a new keyword for this instead of > overloading & for it but apparently this was introduced before C++ was > 'not C'. The idea with the @var, and @var', and @var!, is to not have to use keywords. It's the same idea as not having to write variables which use name tags, like for x using x_in, x_out, or x_inout. I like x, and I like @x to indicate visually that it's a reference. And I think some kind of visual tags like @x' and @x! could be useful as well. They could even be hidden in source code by the EGC, giving it a colorization (rather than a mechanical character) syntax. In any event ... my position's clear. I don't expect C++ to change, but that's really not my goal. I was just curious why the C++ author and ongoing maintainers have created and kept references as they have. Best regards, Rick C. Hodgin |
"Öö Tiib" <ootiib@hot.ee>: May 03 07:19PM -0700 On Tuesday, 3 May 2016 22:40:34 UTC+3, Rick C. Hodgin wrote: > I was not aware C compilers allowed pass-by-ref syntax without some unique > compiler extensions / allowances being used. I thought they were a new > creation provided for by C++. You misread. I wrote that passing by copying the value would need special syntax since passing by reference is more common than passing by value in C++. |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 07:21PM -0700 On Tuesday, May 3, 2016 at 9:10:00 PM UTC-4, Jerry Stuckle wrote: > > in source code so I know it's a reference rather than a value pass. > That's not how references work, Rick. The whole purpose is to *make them > transparent*. Your posts are often difficult for me, Jerry, because you seem to only be able to relate to the way things are, rather than to step outside of the box a little and understand why someone would mention something like this. I mention it because this...: int x, y, z; // x,y,z are populated some_function(x, y, z); ...doesn't convey enough about the operation to know how x, y, and z are used. They could be updated, or not. It's a lacking feature in C++, and while I recognize the way the syntax works today, I think that decision was wrong, and that it should possibly have an option to allow it to not have something like the @x syntax, but I think by default the visual cue should be included and available. > If you want to use "special syntax", use pointers. I want to use special syntax on the passing of parameters, but not on every subsequent use (dereferencing, using -> instead of . and so on). Pointers also convey baggage that values passed by reference don't, such as the need to check for NULL values, which slows down processing, and is redundant when using references. There are reasons to use by-reference values. And for those reasons I want to use them. I just want my source code to indicate to me when I use them that I'm actually using them. Best regards, Rick C. Hodgin |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 07:26PM -0700 On Tuesday, May 3, 2016 at 10:19:21 PM UTC-4, Öö Tiib wrote: > You misread. I wrote that passing by copying the value would need special > syntax since passing by reference is more common than passing by value > in C++. I did misread. My apologies. I think all types should require no special syntax when passed by value, but that all forms passed by pointer or reference should require additional visual syntax so you know it from the place they're used as call parameters. I am also thinking more and more as I get older that pointers and values passed by-ref should be a lot more interchangeable than they are because under the hood, fundamentally, they are the exact same operation, it's just that by-ref values have several advantages, hence their wider use. Best regards, Rick C. Hodgin |
Jerry Stuckle <jstucklex@attglobal.net>: May 03 11:02PM -0400 On 5/3/2016 10:21 PM, Rick C. Hodgin wrote: > Your posts are often difficult for me, Jerry, because you seem to only be > able to relate to the way things are, rather than to step outside of the > box a little and understand why someone would mention something like this. I relate to the way things are because THAT'S THE WAY THINGS ARE. If you don't like it - either suggest a change or use another language. In this case, the change would not be accepted because it would break most of the C++ programs in existence. > was wrong, and that it should possibly have an option to allow it to not > have something like the @x syntax, but I think by default the visual cue > should be included and available. If they aren't going to be updated, then use const, i.e. void some_function(const int x, int y, const int z); In this case, x and z would not be updated, but y may be. >> If you want to use "special syntax", use pointers. > I want to use special syntax on the passing of parameters, but not on > every subsequent use (dereferencing, using -> instead of . and so on). You have a choice - use it all the time, not none of the time. You can't pick and choose when you might want to use it. > Pointers also convey baggage that values passed by reference don't, > such as the need to check for NULL values, which slows down processing, > and is redundant when using references. Actually, not true. It is possible to pass a reference to NULL - although you have to work at it. > use them that I'm actually using them. > Best regards, > Rick C. Hodgin You can use them all of the time, or none of the time. But the function itself can't accept a reference sometimes and a copy other times - just like it can't accept a pointer sometimes, and a copy other times. Use references all of the time, or copies all of the time when calling a function. You can't do both. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 03 09:15PM -0700 On Tuesday, May 3, 2016 at 11:02:33 PM UTC-4, Jerry Stuckle wrote: > > box a little and understand why someone would mention something like this. > I relate to the way things are because THAT'S THE WAY THINGS ARE. If > you don't like it - either suggest a change or use another language. The bulk of my reason for posting today was to propose alternatives, which I have done. And as I've indicated in this thread, I have witnessed the difficulty in getting anything new added to the C or C++ standard. I don't expect anything to change, but my goals here aren't particularly for C++ to change, but to learn of the fundamental reasons why that which is in existence is, in fact, in existence. My goals are CAlive... and I am focused on addressing this issue there. > In > this case, the change would not be accepted because it would break most > of the C++ programs in existence. It would break no C++ programs in existence because the feature would be a new feature that would have to be enabled to be enforced. All legacy code would work without the new syntax constraint, unless that constraint were enabled in the compiler. Only then would it potentially break old code. But, like renaming a global variable temporarily to find all of its usages in a program by looking at the compiler errors, the source code that was broken by the new syntax requirement would be easily found, and resolved. > If they aren't going to be updated, then use const, i.e. > void some_function(const int x, int y, const int z); > In this case, x and z would not be updated, but y may be. And we're again back to square one, that you don't know in the source code whether or not things are being passed are by value, or by reference, without the syntax markup. By requiring the @x syntax for by reference values, and the x' for non- const values, and x! for const values, it would resolve that issue. I'm still not convinced of the x' and x! syntax, though they are growing on me. > > every subsequent use (dereferencing, using -> instead of . and so on). > You have a choice - use it all the time, not none of the time. You > can't pick and choose when you might want to use it. The only place they need to be used are when being passed to something that can change their value. When they're used within the function, they are simply whatever type they are, even if they're by-reference types to some remote data. > > and is redundant when using references. > Actually, not true. It is possible to pass a reference to NULL - > although you have to work at it. I know of know way apart from doing something underhanded, such as using a union with overloaded function calls, or calling a function with a different function declaration which does not match the definition. Internally, the source code generated for both of these is identical. The pointers to main's x,y,z are pushed onto the stack, and their values are updated through the pointer using identical assembly code: void populate1(int& x, int& y, int& z) { x = 12; y = 13; z = 14; } void populate2(int* x, int* y, int* z) { *x = 22; *y = 23; *z = 24; } int main(int argc, char* argv[]) { int x,y,z; populate1(x,y,z); populate2(&x, &y, &z); return(0); } The compiler hides the relaxed syntax requirements on by-ref values for you, but they are still internally identical to pointers. This is why they're so desirable. It is greatly simplified syntax in many cases, and it removes the NULL check requirement. The only issue that is an issue is that you don't know in source code if things are being passed by value or reference by mere inspection. It's my only point in this thread. > You can use them all of the time, or none of the time. But the function > itself can't accept a reference sometimes and a copy other times - just > like it can't accept a pointer sometimes, and a copy other times. FWIW, nobody's asking it to accept something one way part of the time, or not another time. It will always be what it is. My point is that whenever something is passed by reference, it should include the additional syntax. It should not be required in other places. > Use references all of the time, or copies all of the time when calling a > function. You can't do both. You've misunderstood somewhere, Jerry. Best regards, Rick C. Hodgin |
Christian Gollwitzer <auriocus@gmx.de>: May 04 06:58AM +0200 Am 04.05.16 um 04:21 schrieb Rick C. Hodgin: > I want to use special syntax on the passing of parameters, but not on > every subsequent use (dereferencing, using -> instead of . and so on). You can use a reference variable: void inc(int *x_) { int & x = *x_ x++; } int y=2; inc(&y); > Pointers also convey baggage that values passed by reference don't, > such as the need to check for NULL values, which slows down processing, > and is redundant when using references. Yes and no. Pointers can be null, but only if somebody passes in null explicitly. If the function is used in the way shown above, they can't be null. Many APIs segfault when you pass in NULL pointers. What else should happen? Throw an exception? That will always be runtime overhead. In cases where it can't be, the compiler can optimize it away. In cases where it is not clear, a reference does not help. Consider void dec (int &var) { --var; } void buggy (SomeClass *c) { dec(c->member); } buggy(nullptr); Where is the bug? It crashes inside of "dec", because there the memory near zero is written. But there is a reference which "can't be zero". Do you blame "buggy" for not checking the pointer, that it might be zero? Or is it the call? Most C-style APIs, which pass pointers to structs around a lot in this way, blame the caller. Because the typical bug arises from passing in a dangling pointer, such as from a deleted "Object". Christian |
Paavo Helde <myfirstname@osa.pri.ee>: May 04 08:38AM +0300 On 4.05.2016 7:15, Rick C. Hodgin wrote: > On Tuesday, May 3, 2016 at 11:02:33 PM UTC-4, Jerry Stuckle wrote: [...] > const values, and x! for const values, it would resolve that issue. I'm > still not convinced of the x' and x! syntax, though they are growing on > me. The @x! syntax is starting to remind Perl :-( I believe part of the motivation behind reference syntax was to get rid of the special syntax (*x, &x) so that the source code looked cleaner. >> can't pick and choose when you might want to use it. > The only place they need to be used are when being passed to something > that can change their value. This basically means non-const references only. If an object is modified via a const reference (updating a mutable cache variable or locking a mutex, etc), then the caller should not care. >>> and is redundant when using references. >> Actually, not true. It is possible to pass a reference to NULL - >> although you have to work at it. It is possible, bot not legal. So any time you see a "NULL reference" it is clear that this is a bug which must be fixed ASAP, and the fix does *not* involve adding a "NULL reference check" inside the function. > that is an issue is that you don't know in source code if things are > being passed by value or reference by mere inspection. It's my only > point in this thread. Well, that's the point. In my code, I do not want to distinguish passing an object via value or by const reference, because for the caller these are semantically the same, and I do not want to add meaningless noise at the call site. If I need an explicit copy for thread-pass or whatever, I make an explicit copy, no point to hide it in the parameter passing mechanisms. But this is just our coding style and conventions, I understand YMMV. For non-const references I agree that having it highlighted in the calling code might be useful. Alas, this cannot be enforced because this would break zillions lines of existing C++ code. For non-enforced syntax: maybe it would be a solution for you to just create a tool or an IDE extension which goes through the selected source files and adds *& in front of each argument passed via a (non-const) reference? Cheers Paavo |
Robert Wessel <robertwessel2@yahoo.com>: May 04 02:45AM -0500 On Tue, 3 May 2016 12:16:49 -0700 (PDT), "Rick C. Hodgin" > if (x && y && z) > other_thing(*x + *y + *z); > } That's absurd. That references cannot be null are a minor feature of references. Heck it's barely a feature - it's a side effect of how references work. The entire point of references is the syntactical ability to *not* make references explicit in the call. Now if you don't like that feature, just don't use it. If you just wanted non-null references, why not introduce an attribute on pointer parameters in the function. Something like: void f(notnull int *x) Just like "restrict". |
David Brown <david.brown@hesbynett.no>: May 04 10:32AM +0200 On 03/05/16 20:50, Rick C. Hodgin wrote: > } > ?? > Why the need for the additional complexity? The key point is that this solution can be used /today/, using standard C++ compilers. Using an @ sign requires a new language, new compiler, and a good deal of thought to be sure that it is consistent (as shown by the issues around "++x" or "++@x" - after all, when overloaded, "++" is a function that takes a non-const reference). Obviously for your own language, you can use the syntax you want. But this template idea will work for all C++ programmers. It is not a bad idea - I agree with your principle argument that passing data by non-const reference should be clearly indicated in some way (though I want const reference passing to look exactly like value passing). |
Ben Bacarisse <ben.usenet@bsb.me.uk>: May 04 11:33AM +0100 David Brown <david.brown@hesbynett.no> writes: <snip> > The key point is that this solution can be used /today/, using standard > C++ compilers. Using an @ sign requires a new language, new compiler, > and a good deal of thought to be sure that it is consistent You could use *& in place of @. This would enable the idea to be tested: add an option to gcc that will warn when an object is referenced via a non-const reference parameter but where the warning is suppressed if the call uses *&. If it gets wide-spread use, it could be considered for a future C++. It would not be unreasonable to keep *& as the required way to signal "yes, I know this is a non-const reference argument". <snip> -- Ben. |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 04 05:27AM -0700 > That's absurd. That references cannot be null are a minor feature of > references. Heck it's barely a feature - it's a side effect of how > references work. When you say "absurd," do you mean off-the-charts ludicrous? Or is it merely somewhat obtuse? :-) > The entire point of references is the syntactical > ability to *not* make references explicit in the call. I did mention that ability. > on pointer parameters in the function. Something like: > void f(notnull int *x) > Just like "restrict". It's verbose. If x' would indicate change, and x! would indicate no change, and @x indicates by-reference, and &x indicates pointer, then it would be possible to convey typing using: void some_function(int x, int y', int z!, int @a, int @b', int @c!); // x = normal value/object with full range of abilities // y = an out parameter (changed or possibly changed) // z = an in parameter (unchanged) // a = a reference with full range of abilities // b = an out reference (changed or possibly changed) // c = an in parameter (unchanged) It would remove the extra verbosity of typing, while conveying a syntax that can be used in function declaration / definition, as well as in general syntax if desired, and I would argue that it should be used in all cases of passing as a parameter. We'll see though. I'll give it some more thought. Best regards, Rick C. Hodgin |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 04 05:34AM -0700 On Wednesday, May 4, 2016 at 12:58:46 AM UTC-4, Christian Gollwitzer wrote: > } > int y=2; > inc(&y); Makes sense. It never would've occurred to me to do that. By using pointers, it still requires checking for NULL though. > Or is it the call? Most C-style APIs, which pass pointers to structs > around a lot in this way, blame the caller. Because the typical bug > arises from passing in a dangling pointer, such as from a deleted "Object". To answer your question: The bug exists on the dec(c->member); line, or more generally in the buggy() function. NULL values cannot be passed as reference legally, so there needed to be checking done since the source value is a pointer. BTW, in writing this response, it occurred to me that a buggy was a most desirable and essential thing to have ... before the computer age. But since the computer age, not so much, though perhaps for other reasons. :-) Best regards, Rick C. Hodgin |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: May 04 05:37AM -0700 On Wednesday, May 4, 2016 at 4:32:13 AM UTC-4, David Brown wrote: > idea - I agree with your principle argument that passing data by > non-const reference should be clearly indicated in some way (though I > want const reference passing to look exactly like value passing). FWIW, I am amazed sometimes how people would look at a solution like that and say that it's better for general developers than introducing a new feature into the language which simplifies it greatly, such as the @ sign. In any event, as with changes to C, changes to C++ are not my goal. There is no fruit borne in those efforts, so I leave them be. My efforts in asking questions and positing alternatives are for CAlive, not C, or C++. Best regards, Rick C. Hodgin |
David Brown <david.brown@hesbynett.no>: May 04 02:50PM +0200 On 04/05/16 14:37, Rick C. Hodgin wrote: > FWIW, I am amazed sometimes how people would look at a solution like that > and say that it's better for general developers than introducing a new > feature into the language which simplifies it greatly, such as the @ sign. Again, the key point here is that this solution is available here and now, using existing tools. Putting something into your CAlive language may be a fine solution for /you/, but for everyone else, this template solution is infinitely better than "@" because it works /now/. It is conceivable that your @ idea could be so popular that it might be implemented in real-world C++ compilers, or future C++ standards - but at best, that would be many years down the line. And this template solution is not as bad as you seem to think, nor is your @ solution as good. Obviously a lot comes down to opinion and preference, but certainly I would say simple and clear text names like "ref" and "byref" have a lot of advantages over another obtuse symbol such as @. I don't think C++ needs more symbols. (The template definition is of course a one-off. You would just put it in a header somewhere, and forget about the implementation details.) > In any event, as with changes to C, changes to C++ are not my goal. There > is no fruit borne in those efforts, so I leave them be. My efforts in > asking questions and positing alternatives are for CAlive, not C, or C++. That's fine. But it is also nice when it touches on something directly relevant to C and/or C++. In this case, you have a strong point that a number of people agree with at least partially, and it is good to see that there is a workable solution in existing languages. It is also fine if you want to solve the problem in a somewhat different matter in your own language. And it's fine that /your/ main concern here is CAlive - but you should not be surprised to see that most people's main concern in this newsgroup is C++. |
scott@slp53.sl.home (Scott Lurndal): May 04 12:48PM >You might find my blog post on the PLATO @ 50 conference interesting: ><https://legalizeadulthood.wordpress.com/2010/06/28/plato50-conference/> ><https://legalizeadulthood.wordpress.com/2010/06/24/plato50-conference-video/> FWIW, DEC had a Tutor language system available for the VAX at one point. We couldn't convince the Pellets to give up the source for DnD, however, so that we could port it to the VAX (using GIGI terminals for the graphics, although the DnD graphics could likely have been reproduced using the VT100 line drawing character set). |
Robert Wessel <robertwessel2@yahoo.com>: May 04 02:47AM -0500 |
ram@zedat.fu-berlin.de (Stefan Ram): May 04 10:21AM > std::vector<int> v({47,11}); > auto it=find(v,47); >} I did not bother to really understand the error message, and I don't know whether it's the following that you want, but this compiles here (-std=c++17): #include <algorithm> #include <vector> #include <utility> template< typename T > typename T::const_iterator find ( const T & c, const typename T::value_type & val ) { return ::std::find( cbegin( c ), cend( c ), val ); } int main() { ::std::vector< int >v{ 47, 22 }; auto it = find( v, 47 ); } ; or, with a non-const iterator: #include <algorithm> #include <vector> #include <utility> template< typename T > typename T::iterator find ( T & c, typename T::value_type const & val ) { return ::std::find( begin( c ), end( c ), val ); } int main() { ::std::vector< int >v{ 47, 22 }; auto it = find( v, 47 ); } . |
ram@zedat.fu-berlin.de (Stefan Ram): May 04 11:07AM >Okay, thanks. This does the trick even with "const T & c". But why don't >we need namespace qualifier std:: in front of "begin" and "end"? It's called »Koenig lookup« or »argument-dependent lookup« (»ADL«). (»::std::« might even be wrong, when the name is not in that namespace at all.) >According to http://www.cplusplus.com/reference/iterator/begin/ that's >where these functions live. And what do you need <utility> for. Here it >works without it (std=c++11) I was not sure about the header required for »begin«, and I guessed that it might have been »<utility>«. I was too lazy to look it up. I did not want to convey that it was necessary. |
Ralf Goertz <me@myprovider.invalid>: May 04 11:52AM +0200 Hi, I find it quite tedious to always have to write auto it=std::find(v.begin(),v.end(),value); where "v" is a suitable container of elements of the same type as "value". I almost never want so search in a proper subrange. So now that we have stuff like for (auto i:v) … to indicate that we want "i" to iterate over all elements of "v" I came to wonder why there is no auto it=std::find(v,value); [1] or at least auto it=std::find(v.begin(),value); [2] Looking at the substr() and erase() member function of string it seems there are function prototypes which help avoid unnecessary typing. I know that variant [2] would be difficult given that it would be hard to know what v.end() is from within the function. But why not provide [1] in a way similar to this?: #include <algorithm> #include <vector> template <class C> typename C::iterator find (const C &c, const typename C::value_type & val) { return std::find(c.begin(),c.end(),val); } int main() { std::vector<int> v({47,11}); auto it=find(v,47); } However, this gives an error: find_test.cc: In instantiation of 'typename C::iterator find(const C&, const typename C::value_type&) [with C = std::vec tor<int>; typename C::iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; typename C::value_type = int]': find_test.cc:12:22: required from here find_test.cc:6:43: error: could not convert 'std::find<__gnu_cxx::__normal_iterator<const int*, std::vector<int> >, int> ((& c)->std::vector<_Tp, _Alloc>::begin<int, std::allocator<int> >(), (& c)->std::vector<_Tp, _Alloc>::end<int, std::all ocator<int> >(), (* & val))' from '__gnu_cxx::__normal_iterator<const int*, std::vector<int> >' to 'std::vector<int>::it erator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' return std::find(c.begin(),c.end(),val); ^ Omitting the "const" in front of "C &c" makes it compile. But then I can't search in const vectors. Is there a way that works? Ralf |
Ralf Goertz <me@myprovider.invalid>: May 04 01:00PM +0200 Am 4 May 2016 10:21:21 GMT > I did not bother to really understand the error message, > and I don't know whether it's the following that you want, > but this compiles here (-std=c++17): <snip> > ( T & c, > typename T::value_type const & val ) > { return ::std::find( begin( c ), end( c ), val ); } Okay, thanks. This does the trick even with "const T & c". But why don't we need namespace qualifier std:: in front of "begin" and "end"? According to http://www.cplusplus.com/reference/iterator/begin/ that's where these functions live. And what do you need <utility> for. Here it works without it (std=c++11) |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment