Wednesday, February 10, 2016

Digest for comp.lang.c++@googlegroups.com - 23 updates in 10 topics

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: