On 19/06/2012, at 6:42 AM, James Dennett wrote: > On Sun, Jun 17, 2012 at 4:02 PM, john skaller > <skal...@users.sourceforge.net> wrote: >> The failure of the strdict-01 regression test on Windows has >> again highlighted the design fault in strings .. both Felix and C++. >> >> When you call >> >> char const *p = string("hello").c_str(); >> >> in C++ you have a dangling pointer p. The call succeeds because >> string("hello") is a non-const rvalue, but there's no mechanism >> in C++ for a method to require an lvalue object: you can insist >> that a function argument is an lvalue, but not the object of a non-static >> member function. > > That was fixed in C++11. The syntax is something like: > > struct S { > void f() &; > }; > > where the default is that *this can be either an lvalue or an rvalue, > and users can write "&" or "&&" to restrict to one or the other. > Compilers have been a touch slow implementing this though.
Ah. That's N2439 by the look of it and it's been in clang since version 2.9 (latest stable is 3.1),. Gcc pages says: Ongoing C++11 Development Rvalue references for *this Bronek Kozicki has been working on this feature. > > However: in C++ it's often convenient and correct to call c_str() on a > temporary -- e.g., printf("...%s\n", (string("this") + " and > that").c_str()). The temporary isn't destroyed until after the printf > call returns, and all is well. Yep, Felix does this in C++ implementations all the time, safely. But the Felix function cstr x cannot do this safely: it then depends on the user being careful (i.e. it isn't safe), and that's MUCH harder to do in Felix than in C++ because Felix has much "weaker" semantics to allow much better optimisation than C++ can dream of. It's possible to control this in Felix .. but that's the problem: you actually have to actively control it. Just to explain, in C++ void f(x:string) { ... } in the body of f, x is an object with a determinate lifetime. Even if C++ compiler inlines the function, or does optimisations, it must respect these semantics. In Felix it is the same with fun f(var x:string) = { .. } but if you write instead: fun f(x:string) = { .. } it means fun f(val x:string) = { .. } which tells Felix to treat x as a value, not an object. Felix is allowed to do eager evaluation like the "var" case and assign the argument to a variable, OR, it is allowed to just replace "x" in the body of the function with the actual argument. If the function f is inlined it is likely it will use the lazy evaluation strategy. [Because it's almost always faster] It may also factor your code. So you may end up with: char * p = string("hello").c_str(); which has unspecified semantics and will probably corrupt your program. Indeed this actually DOES happen. > C++ specifies exactly when the temporaries are destroyed, specifically > at the end of the "full expression", and the only compiler I've seen > deviate from it recently (within the last decade) was Sun's. The > exception is when copy/move-elision reduces the number of objects, as > you've noted below. Indeed, but the Felix compiler generates C++ code without respecting the notion of "full expression". The compiler considers itself free to factor any expression into a series of assignments and a simpler expression, that is, roughly "Three address code": f ( g ( h (x))) can be changed to hx = h (x) ghx = g (hx) f (ghx) This is safe in Felix, because Felix does not have any references: we only have values, and use pointers for objects. Felix pointers are garbage collected. the problem is interfacing to C and C++ where there is "hidden" internal pointers that C++ allows to be stolen, such as with most STL containers including strings. Those pointers are not managed by Felix GC, and they're not managed by C++ either. They have to be managed by the programmer, so they're not safe. This normally isn't a problem in Felix UNLESS the programmer makes a binding of a C/C++ data type. in this case the programmer is ME, binding the Felix string type to the C++ string type. Unfortunately we HAVE to support char* string types as well as C++ string types because we have to interface with C code .. exactly the same reason C++ has to support it too. -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language