- Making template instantiation fail - 3 Updates
- "Rust vs. C++: Fine-grained Performance" - 4 Updates
- Derivation without size increase? - 4 Updates
- Unit testing (Re: Putting project code in many different files) - 1 Update
- Making all getters- return values const? - 1 Update
- Putting put-downs in many different posts - 2 Updates
- dynamic_cast considered annoying - 5 Updates
- cmsg cancel <n8u511$mog$2@dont-email.me> - 1 Update
- OT: Tonto (was Re: Let's talk about multiple inheritance and interfaces.) - 1 Update
- 'int' considered dangerous (reprise) - 1 Update
| Jorgen Grahn <grahn+nntp@snipabacken.se>: Feb 10 08:03PM It occurred to me to ask an actual question, rather than involving myself in the usual arguments about swearing and so on ... The other day I wrote this one: /* Consume a 16-bit integer from a sequence of * uint8_t or similar, big-endian. */ template <class Iter> unsigned eat16(Iter& i) { unsigned n = *(i++); n = n << 8 + *(i++); return n; } I can accept if it fails silently when I feed in a vector<unsigned>, list<unsigned long> iterator etc. But it would also fail silently if I feed it a char*, or a vector<char>::iterator -- and that's not acceptable to me. Question: what's the canonical C11 way to make the template fail if 'i' doesn't iterate over a bunch of unsigned things? Seems like the kind of thing people would do all the time. I played with static_assert(), std::is_unsigned and decltype(*i), but couldn't get it to work within reasonable time. Should I (and this just occurred to me) use std::iterator_traits<Iter>::value_type rather than decltype(*i)? This seems to work: /* Consume a 16-bit integer from a sequence of * uint8_t or similar, big-endian. */ template <class Iter> unsigned eat16(Iter& i) { typedef std::iterator_traits<Iter> traits; static_assert(std::is_unsigned<typename traits::value_type>::value, "unsigned, dammit!"); unsigned n = *(i++); n <<= 8; n += + *(i++); return n; } I'm not used to doing these kinds of things. Usually I leave it up to the caller to make sure the template argument is sane -- but this is in a context where I use Boost, and I'm less sure of the types involved than I normally am. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
| Paavo Helde <myfirstname@osa.pri.ee>: Feb 11 12:11AM +0200 On 10.02.2016 22:03, Jorgen Grahn wrote: > n += + *(i++); > return n; > } If you just want to detect invalid usage, static_assert should be fine, and the above should be kosher as far as the incoming iterator type is defined correctly. OTOH, going over decltype should work also with iterators which do not have proper traits defined. This should probably look something like: static_assert(std::is_unsigned<typename std::remove_reference<decltype(*i)>::type>::value, "unsigned, dammit!"); |
| Jorgen Grahn <grahn+nntp@snipabacken.se>: Feb 10 11:11PM On Wed, 2016-02-10, Paavo Helde wrote: > static_assert(std::is_unsigned<typename > std::remove_reference<decltype(*i)>::type>::value, > "unsigned, dammit!"); Thanks -- that looks like my first attempt, minus some bugs which might explain why mine didn't work properly ... /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
| Juha Nieminen <nospam@thanks.invalid>: Feb 09 11:54PM > (the package and dependency manager cargo, rustdoc). Unit-Testing > is easy and painless. The process of adding to the language is open > and documented. I'm excited to see where this is all going. C++ has one pragmatic advantage that most non-compatible languages do not: If I need a library for some specific task, there are really high chances that there will be a decent C (sometimes even C++) library out there that does exactly that. For almost any problem you might imagine. I have no idea if C libraries can be used in Rust, but if they can't, then that's a big point against it. Sure, its library of libraries (hah!) may be constantly increasing, but it's doubtful it will be reaching the vastness of the C/C++ libraries out there. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
| Paavo Helde <myfirstname@osa.pri.ee>: Feb 10 12:27PM +0200 On 10.02.2016 1:54, Juha Nieminen wrote: > high chances that there will be a decent C (sometimes even C++) library > out there that does exactly that. For almost any problem you might > imagine. +1 A side note: in my experience it is often easier to use C libraries than C++, because of all the ABI and language incompatibilities. Even if the library is written itself in C++, it might be useful to create a C interface on top of that. The C interface could be wrapped in a thin C++ header-only wrapper which creates or restores RAII and maybe automates some parameter conversions. There are exceptions like Boost or TinyXML which are either extensively tested and maintained or just so simple that they compile with everything and cause no headaches. But even with Boost there are occasional hiccups when new compiler versions come out. > I have no idea if C libraries can be used in Rust, A quick google search says Rust can use C libraries, but not C++. This just adds another argument for creating C interfaces for C++ libraries. Cheers Paavo |
| SG <s.gesemann@gmail.com>: Feb 10 04:23AM -0800 Am Mittwoch, 10. Februar 2016 00:54:39 UTC+1 schrieb Juha Nieminen: > high chances that there will be a decent C (sometimes even C++) library > out there that does exactly that. For almost any problem you might > imagine. Yes. This is obviously the case for every young language. I mentioned it in the paragraph that followed the one you quoted. > I have no idea if C libraries can be used in Rust, but if they can't, > then that's a big point against it. Many Rust libraries you can find are actually bindings to other C libraries (SDL2, PortAudio, lower level async I/O, ...). Rust supports calling C functions and Rust can expose a function with C linkage in order to allow C code to call Rust code. But all this happens outside of the safe subset of Rust. So, the strategy for using some C library from Rust is to add a Rust layer on top that exposes a safe and Rusty interface. For example, if some C library offers an interface like this: struct opaque_context_s; typedef struct opaque_context_s opaque_context_t; // might return NULL in case something went wrong opaque_context_t* create(); void destroy(opaque_context_t*); // warning: the returned char pointer is only valid // until you destroy the context!!! const char* get_name(opaque_context_t*); This is usually wrapped in Rust RAII-style like this: // private declarations for the C interface of the library... enum Opaque {} extern fn create() -> *mut Opaque; extern fn destroy(handle: *mut Opaque); extern fn get_name(handle: *mut Opaque) -> *const ffi::c_char; // public Rust interface layer... pub struct Context { // our RAII wrapper handle: *mut Opaque, } impl Drop for Context { // "destructor" fn drop(&mut self) { unsafe { destroy(self.handle); } } } impl Context { pub fn new() -> Result<Self,()> { let raw = unsafe { create() }; if raw.is_null() { return Err(()); } Ok(Context { handle: raw }) } pub fn get_name(&self) -> &ffi::CStr { unsafe { let raw = get_name(self.handle); ffi::CStr::from_ptr(raw) } } } You could write something similar in C++. After all, resource management in Rust is heavily inspired by C++. But an important difference here is that the warning you saw in the documentation of the C interface is actually encoded in the Rust signatures in a way that the compiler understands them and checks for. The easy way would have been to immediately convert the char* to an owned string and return it by value from the get_name method to avoid lifetime issues. But in Rust we can do better. The full return type of get_name is actually "&'x CStr", a reference that refers to the C string allocated by the C library constrained by a some lifetime parameter "x" that in this case is implicitly tied to the lifetime of the *self object by one of the lifetime elision rules of the core language. The Rust compiler would not allow us to hold on to this &CStr after the RAII wrapper ceases to exist. The following code snippet that contains such a use-after-free error would not compile: fn foo() -> Result<&ffi::CStr,()> { let short_lived = try!(Context::new()); return short_lived.get_name(); } This way, we provided a Rust interface that does not allow the user create use-after-free errors while avoiding unnecessary heap allocations for temporary string objects. Magic! :) sg |
| woodbrian77@gmail.com: Feb 10 03:00PM -0800 On Wednesday, February 10, 2016 at 4:27:36 AM UTC-6, Paavo Helde wrote: > > out there that does exactly that. For almost any problem you might > > imagine. > +1 They also don't seem to have anticipated on line code generation. Brian Ebenezer Enterprises - In G-d we trust. http://webEbenezer.net |
| David Brown <david.brown@hesbynett.no>: Feb 10 10:52AM +0100 On 09/02/16 19:15, Jerry Stuckle wrote: >> On 09/02/16 15:13, Chris Vine wrote: >>> On Tue, 09 Feb 2016 14:14:00 +0100 >>> David Brown <david.brown@hesbynett.no> wrote: <snip> >>>> down whale blubber to oil. (There is a popular myth that it comes >>>> from Thomas Crapper, the inventor of the ball-and-cock mechanism of >>>> toilets.) <snip> > Actually, I think the U.S. usage anyway came from a Londoner - Thomas > Crapper. While the common belief is that he invented the flush toilet, > he really didn't. He did, however, increase its popularity. Jerry, do you know why a "newsreader" program is called a "newsreader"? It is because it allows you to /read/ postings on Usenet. Look a little above, and you'll see that Thomas Crapper has already been mentioned. > And during WWI, soldiers visiting the facilities would "take a crap". <http://www.snopes.com/business/names/crapper.asp> |
| Jerry Stuckle <jstucklex@attglobal.net>: Feb 10 09:14AM -0500 On 2/10/2016 4:52 AM, David Brown wrote: > Jerry, do you know why a "newsreader" program is called a "newsreader"? > It is because it allows you to /read/ postings on Usenet. Look a > little above, and you'll see that Thomas Crapper has already been mentioned. I did. I'm just pointing out that's why in the United States. Can you post anything without an insult? >> And during WWI, soldiers visiting the facilities would "take a crap". > <http://www.snopes.com/business/names/crapper.asp> http://www.urbandictionary.com/define.php?term=Crapper -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
| woodbrian77@gmail.com: Feb 10 10:52AM -0800 On Tuesday, February 9, 2016 at 7:14:22 AM UTC-6, David Brown wrote: > > by judicial authorities. > > What about the word "damn" do you regard as offensive? > Maybe his concern was the word "crap" - which is not really swearing I don't think "crap" is swearing. http://www.wikihow.com/Stop-Swearing Brian Ebenezer Enterprises http://webEbenezer.net |
| Ian Collins <ian-news@hotmail.com>: Feb 11 08:04AM +1300 >>> What about the word "damn" do you regard as offensive? >> Maybe his concern was the word "crap" - which is not really swearing > I don't think "crap" is swearing. So what did you object to? -- Ian Collins |
| Paavo Helde <myfirstname@osa.pri.ee>: Feb 10 09:49AM +0200 On 10.02.2016 1:20, Richard wrote: > [Please do not mail me a copy of your followup] > Oh come on, Paavo. There's plenty of room left in your KILL file, so > just save yourself the grief :). What grief? Nit-picking Flibble is just fun! :-) Cheers Paavo |
| JiiPee <no@notvalid.com>: Feb 05 03:41AM On 05/02/2016 02:59, Alf P. Steinbach wrote: > As a result the proposed rules were changed. I guess the lesson is that do not read too carefully older C++ books |
| Ian Collins <ian-news@hotmail.com>: Feb 05 08:22AM +1300 Daniel wrote: > How do you organize your put-downs with regards to the number of posts you make? Lets say you have 20-30 different put-downs and each takes one to two lines of text, e.g. "you apparently haven't worked since the PC was invented", "leave you there in your own little out-of-date pigsty". Would you separate them to different posts or put them in the same post? Is it a good idea to have a lot of smaller put-downs in a post, or combine them? Please learn to wrap your lines :) -- Ian Collins |
| David Brown <david.brown@hesbynett.no>: Feb 04 09:44PM +0100 On 04/02/16 18:06, Daniel wrote: > out-of-date pigsty". Would you separate them to different posts or > put them in the same post? Is it a good idea to have a lot of smaller > put-downs in a post, or combine them? I'd say separate them, and try not to use the same put-down multiple times. After all, a put-down has to be appropriate (used for someone well beyond listening to reason), and it should not be too annoying to other readers. So avoiding repetition is good, as is being witty in some way. It can be okay to cut-and-paste the same put-down multiple times in one reply, where the post is just so hopelessly wrong that it is too much effort to correct. But repeating the same rather dull put-down in multiple posts is poor style, IMHO. |
| Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 04 12:00PM Check out my codes! void radio_button::set_on_state(bool aOnState) { if (iOnState != aOnState) { if (aOnState) { i_widget* candidate = &link_after(); while (candidate != this) { if (is_sibling(*candidate)) { // Teh ghastly dynamic_cast! A simpler CLEAN solution which doesn't leak details everywhere doesn't immediately spring to mind. radio_button* candidateRadioButton = dynamic_cast<radio_button*>(candidate); if (candidateRadioButton != 0) candidateRadioButton->set_on_state(false); } candidate = &candidate->link_after(); } } iOnState = aOnState; update(); if (is_on()) on.trigger(); else if (is_off()) off.trigger(); } } /Flibble |
| Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 04 12:56PM On 04/02/2016 12:45, Mr Flibble wrote: >> radio_button::is_sibling(i_widget*)'. > link_after and is_sibling are members of widget base class but yes > "next_radio_button" would be better. const radio_button* radio_button::next_radio_button() const { const i_widget* candidate = &link_after(); while (candidate != this) { if (is_sibling(*candidate)) { // Teh ghastly dynamic_cast! A simpler CLEAN solution which doesn't leak details everywhere doesn't immediately spring to mind. const radio_button* candidateRadioButton = dynamic_cast<const radio_button*>(candidate); if (candidateRadioButton != 0) return candidateRadioButton; } candidate = &candidate->link_after(); } return this; } radio_button* radio_button::next_radio_button() { return const_cast<radio_button*>(const_cast<const radio_button*>(this)->next_radio_button()); } void radio_button::set_on_state(bool aOnState) { if (iOnState != aOnState) { if (aOnState) for (radio_button* nextRadioButton = next_radio_button(); nextRadioButton != this; nextRadioButton = nextRadioButton->next_radio_button()) nextRadioButton->set_on_state(false); iOnState = aOnState; update(); if (is_on()) on.trigger(); else if (is_off()) off.trigger(); } } /Flibble |
| Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 04 12:45PM On 04/02/2016 12:31, Öö Tiib wrote: >> /Flibble > May be have 'radio_button* radio_button::next_sibling()' instead of what seem > to be 'i_widget* radio_button::link_after()' and 'bool radio_button::is_sibling(i_widget*)'. link_after and is_sibling are members of widget base class but yes "next_radio_button" would be better. /Flibble |
| Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 04 03:13PM On 04/02/2016 14:56, Öö Tiib wrote: > 'dynamic_cast' with 2 virtual calls ('accept' of object calls 'visit' of visitor) > so it is not more efficient. Also some people hate the pattern. However > there won't be need for 'typeid' or 'dynamic_cast' with it. Visitor pattern wouldn't be appropriate in this instance as it would involve creating a closed (class) leaky abstraction (the visitor interface). /Flibble |
| Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 04 06:52PM On 04/02/2016 17:17, Öö Tiib wrote: > { > v.visit(*this); > } It leaks into the widget_visitor interface which has to know about radio buttons: widget_visitor would be a closed class yet would have to have a visit method for each widget type which just isn't feasible. /Flibble |
| bleachbot <bleachbot@httrack.com>: Feb 04 01:15AM +0100 |
| Vir Campestris <vir.campestris@invalid.invalid>: Feb 02 09:16PM On 02/02/2016 00:56, Jerry Stuckle wrote: >> Andy > Tonto was an American Indian name (I forget which tribe), not Spanish. > Tonto was the name of the Lone Ranger's partner. I thought you might be on to something when I found this <https://en.wikipedia.org/wiki/Tonto_Apache> Then I read on... "The Tonto Apache (Dilzhę́'é, also Dilzhe'e, Dilzhe'eh Apache) is one of the groups of Western Apache people. The term is also used for their dialect, one of the three dialects of the Western Apache language (a Southern Athabaskan language). The Chiricahua living to the south called them Ben-et-dine or binii?e'dine' ("brainless people", "people without minds", i.e. "wild", "crazy", "Those who you don't understand").[1] The neighboring Western Apache ethnonym for them was Koun'nde ("wild rough People"), from which the Spanish derived their use of Tonto ("loose", "foolish") for the group. The kindred but enemy Navajo to the north called both, the Tonto Apache and their allies, the Yavapai, Dilzhʼíʼ dinéʼiʼ - "People with high-pitched voices")." Andy |
| Juha Nieminen <nospam@thanks.invalid>: Feb 01 09:20AM > 'int' considered dangerous: use a <cstdint> sized integer typedef instead. It depends on what you are doing. If you are writing a library that should be as portable as possible, and expected to be used in wildly different platforms, from ols small embedded systems to modern 64-bit processors, then perhaps. If, however, you are writing closed-source software for a specific platform (let's say, for example, iOS), then it might even be better to use int for integers whose maximum size is irrelevant. On that particular platform you can be sure that int will have a minimum size and will never get smaller even in future versions of that platform, so you'll be A-ok. Why use int instead of an equivalent std type? Because 'int' is ostensibly always the most efficient integral type of the system, even in future versions of the platform. You'll never know if the std type you chose will be the most efficient in a future version. > On a related matter eschewing unsigned integer types is foolish as one > should use an unsigned type when dealing with unsigned values. unsigned causes problems when it's mixed with signed types. And this happens quite easily. Example: Image size cannot be negative. Negative values are nonsensical. Therefore it makes sense to use unsigned to store image dimensions? In theory yes. In practice you'd better use a signed type because image coordinates *can* become negative in many situations (eg. line drawing, or sprite coordinates), and you'll run into problems when mixing signed coordinates with unsigned image sizes. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
| 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