Saturday, January 9, 2016

Digest for comp.lang.c++@googlegroups.com - 12 updates in 4 topics

Barry Schwarz <schwarzb@dqel.com>: Jan 08 11:32AM -0800

On Fri, 8 Jan 2016 09:58:36 -0800 (PST), Paul <pepstein5@gmail.com>
wrote:
 
 
>My questions are as follows:
>1) The u at the end of 0xffu seems redundant. It just means the bit pattern 11111111.
>If there were 16 fs instead of 2fs, then it would be relevant, however. Am I correct that the u is redundant?
 
I didn't try to determine if it makes a difference to the book's code
but the constant 0xff has type (signed) int and 0xffu has type
unsigned int. Since this constant is only used in conjunction with
the unsigned parameter n, having it unsigned eliminates the need to
perform any of the "usual arithmetic conversions" that occur when
signed and unsigned appear in the same expression.
 
>2) Does the word "static" in this context mean that bitInChar shouldn't change its value
>between function calls? What do we gain from the "static" concept here? If we
 
Since bitInChar is defined at file scope, its value is not dependent
on function calls. It only changes value when assigned to. What the
static qualifier does is give the name internal linkage which prevents
it from being accessed by name from a different translation unit.
 
>}
 
>3) How about the following idea of mine below? We don't want to waste time with fillBitsInChar() multiple
>times. So maybe we can have a static bool to make sure it's only done once. Is this code immediately below ok?
 
It is completely unnecessary. The expectation is your code would call
fillBitsInChar exactly once before you ever called
countBitsConstantFor32BitsInt, which you could then call as often as
you wanted. (Similar to calling srand exactly once before calling
rand as often as needed.)
 
>}
 
>I think I've answered my own question because my idea doesn't work if bitChar is
>not static. Have I correctly understood why "static" is used by the author?
 
Did you mean bitInChar? In what way does it not work? Without the
specifier static, bitInChar has external linkage and therefore static
duration. This means its lifetime is the entire execution of the
program and it retains its last_stored value throughout that lifetime.
The only effect the specifier has is to change the linkage from
external to internal.
 
 
--
Remove del for email
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 09 08:14AM

On Fri, 2016-01-08, Paavo Helde wrote:
 
> He did not say that. He said that he would not read the rest of the
> question. Without reading, how could he tell if he can or wants to
> answer the question?
 
What really happened was I was tired and had a cold. I was happy to
see the reference, so thanking him for it (and going offtopic with
some loose feelings about how books should work, apparently) felt like
something I should do immediately.
 
> Maybe he will answer later if he feels like so and
> has spare time, maybe not.
 
After Paul named the book like I asked him to, I feel obliged to read
it. (I should probably have stated that explicitly to avoid this
subthread.)
 
But perhaps I have nothing interesting to say; we'll see.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 09 08:48AM

On Fri, 2016-01-08, Paul wrote:
> On Friday, January 8, 2016 at 6:14:24 PM UTC, Scott Lurndal wrote:
>> Paul <pepstein5@gmail.com> writes:
...
>> >My questions are as follows:
 
The code was something like:
 
unsigned n = something;
some_array[ n & 0xffu ];
 
 
>> If the 'u' isn't present, the compiler assumes it is a signed integer and
>> will sign-extend it to 32-bits. That would be bad, since the intent in the
>> code you've posted is to mask off all but the low-order 8 bits.
 
But bad in what sense? 0xff is an int, and it's never negative since
int IIRC is at least 16 bits.
 
It's unclear to me what happens in 'n & 0xff': if both are promoted to
int, or to unsigned. (I checked TC++PL, but failed to find anything
useful. I should really know these rules, but I think I instead tend
to stay away from the gray areas ...)
 
In practice I write those things like the book did, and I never got
even a warning from the compiler. On the other hand, when I use bit
operations like & or shifting, I always feel better if all the types
involved are unsigned, so I can't really complain about that 'u'.
 
...
 
> On my machine 0xff == 0xffu evaluates as true.
 
They do on every machine. It only gets interesting when you try
0xffffffff == 0xffffffffu on a machine with 32-bit ints, and I don't
know what happens then -- probably a warning from the compiler.
 
> If the u is necessary, could 0xff be unequal to 0xffu with different
> endianness?
 
Whatever happens, endianness never enters the picture. You can't see
endianness differences unless you use pointers and casts to break
through the type system down to the raw memory beneath.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
David Brown <david.brown@hesbynett.no>: Jan 09 02:38PM +0100

On 09/01/16 09:48, Jorgen Grahn wrote:
> int, or to unsigned. (I checked TC++PL, but failed to find anything
> useful. I should really know these rules, but I think I instead tend
> to stay away from the gray areas ...)
 
Since "n" is an unsigned int, both get promoted to unsigned.
 
But promotion of (signed) 0xff to unsigned does not change its value -
as you say, "int" must be at least 16 bit.
 
However, while the "u" in 0xffu is redundant as far as the meaning and
operation of the code is concerned, it is not bad practice to make it
clear to the reader that you are dealing entirely with unsigned integers
here.
 
Paul <pepstein5@gmail.com>: Jan 09 05:48AM -0800

On Saturday, January 9, 2016 at 1:39:07 PM UTC, David Brown wrote:
> operation of the code is concerned, it is not bad practice to make it
> clear to the reader that you are dealing entirely with unsigned integers
> here.
 
Yes, this can also be directly tested by
std::cout << typeid(1u & 0xff).name();
 
The result is j which denotes unsigned.
 
Paul
Paul <pepstein5@gmail.com>: Jan 09 06:06AM -0800

On Saturday, January 9, 2016 at 8:15:10 AM UTC, Jorgen Grahn wrote:
> it. (I should probably have stated that explicitly to avoid this
> subthread.)
 
> But perhaps I have nothing interesting to say; we'll see.
 
Ok, thanks for the clarification. I've received a lot of help on this topic already from everyone on this thread, and have no further questions. The author of the book has a great concept -- a series of books on c++ interviews, each focusing on a particular topic -- for example, bit manipulation in c++, dynamic programming in c++ etc. etc. Even if the code and explanations are not great, I think it's a wonderful concept and am looking at the books in this series on that basis.
 
In other words, I'm sure there are other books which explain bit manipulation better. But I doubt there is a better book on the precise topic of bit manipulation in c++ interviews. The reason I doubt this is that I would expect that such a niche topic only has one book devoted entirely to it.
 
From experience, I felt that referencing the book would elicit a massive subthread attacking and defending the book and I wanted to avoid going off-topic.
 
Having said that, I welcome opinions on these books. I have the whole series, and would be interested in feedback. Although I already have them, opinions on whether they're good or bad may well influence how much time I spend on them.
 
The books are all by Antonio Gulli and are called:
A collection of bit programming interview questions solved in c++
A collection of design pattern interview questions solved in c++
A collection of dynamic programming interview questions solved in c++
A collection of graph programming interview questions solved in c++
A collection of tree programming interview questions solved in c++
 
Paul
"Öö Tiib" <ootiib@hot.ee>: Jan 09 07:38AM -0800

On Saturday, 9 January 2016 15:48:36 UTC+2, Paul wrote:
 
> Yes, this can also be directly tested by
> std::cout << typeid(1u & 0xff).name();
 
> The result is j which denotes unsigned.
 
On MSVC it is "unsigned int" already and with GCC it is easy to get
"unsigned int" as well, we just need to wrap their __cxa_demangle
to a function with sane C++ interface:
 
#include <iostream>
#include <memory>
#include <string>
#include <cxxabi.h>

std::string demangle(char const* name)
{
using c_char_ptr = std::unique_ptr<char, decltype(std::free)*>;
 
int status = -4;
c_char_ptr res {abi::__cxa_demangle(name, NULL, NULL, &status)
, std::free};
return (status==0) ? res.get() : name;
}
 
int main()
{
std::cout << demangle(typeid(1u & 0xff).name()) << '\n';
}
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 09 07:33AM +0100

On 1/8/2016 7:43 PM, Richard wrote:
 
> - static_cast
> - const_cast
> - reinterpret_cast
 
OK.
 
> I think the compiler is even free to do dynamic_cast.
 
No, but it can cast to inaccessible base, as a `static_cast` would have
done (including possible address adjustment) if it had been accessible.
 
 
> reading the code, you not only don't know what you're getting from the
> compiler without thinking really hard about it, you have no idea what
> the original programmer *intended* when they wrote the C style cast.
 
Cheers & hth.,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 08 01:00PM +0100

I just coded up the following to automate selection of a type for a
formal in-argument:
 
namespace impl {
template< class Type >
constexpr auto is_large_or_incomplete()
-> bool
{
return (sizeof_<Type>() == 0
? true
: sizeof_<Type>() > sizeof( Ptr_<void> )
);
}
} // namespace impl
 
template< class Arg >
using In_ = If_<
Any_of_<
Is_true_<impl::is_large_or_incomplete<Arg>()>,
Is_raw_array_<Arg>
>,
Then_<Ref_<const Arg>>,
Else_<const Arg>
>;
 
where "sizeof_" is a constexpr function that yields 0 for an incomplete
type.
 
Then when I started using this in the existing other code, it hit me that
 
• In a function declaration within class Foo, "In_<Foo>" will translate
to "Foo const&", because here Foo is still incomplete.
 
• But in a function definition after the Foo class definition,
"In_<Foo>" can translate to just "Foo const", because here Foo is complete.
 
So I'm not at all sure that the above is a good design. Should, instead,
e.g. incomplete argument type just not compile with automated selection
of the specific form? Or, maybe the whole idea of writing
 
void f( In_<Foo> x )
 
instead of e.g. (for array or large type)
 
void f( Foo const& x )
 
is ungood?
 
 
Cheers,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 09 02:36AM +0100

On 1/8/2016 1:00 PM, Alf P. Steinbach wrote:
 
> • But in a function definition after the Foo class definition,
> "In_<Foo>" can translate to just "Foo const", because here Foo is complete.
 
> So I'm not at all sure that the above is a good design.
 
Well, I landed on a compromize: always translating "In_<T>" to reference
when "T" is a class type (and also when "T" is a raw array type). That
avoids any problems with incomplete type within a class definition. When
the small object should be passed by value, that can always be specified
explicitly as e.g. "In_value_<T>":
 
<code>

//---------------------------------------------------------------------------
// Formal argument types:
 
// Works with template argument deduction, but is just a clarity
notation
// (descriptive, and removes from sight a visually distracting
`const`).
template< class Arg >
using In_ref_ = Ref_<const Arg>; // ← In_ref_
 
// Works with template argument deduction, but is just a clarity
notation
// (descriptive, and removes from sight a visually distracting
`const`).
template< class Arg
, class Enabled_ = If_<Not_<Is_raw_array_<Arg>>>
 
using In_value_ = const Arg; // ← In_value_
 
// Automated argument type selection.
// Note: can't work with template argument deduction; stricly for
known types.
template< class Arg >
using In_ = If_< // ← In_
Any_of_< std::is_class<Arg>, Is_raw_array_<Arg> >,
Then_<Ref_<const Arg>>,
Else_<const Arg>
>;
 
// Works with template argument deduction.
template< class Arg
, class Enabled_ = If_<Not_<std::is_const<Arg>>>
 
using In_out_ = Ref_<Arg>; // ← In_out_
</code>
 
The visual effect on function declarations can be seen in the latest
check-in of the cppx code, at <url:
https://github.com/alf-p-steinbach/cppx/commit/a5a185e781bc1b06971c4fc869dbefe2e0ea687c>.
 
Cheers!,
 
- Alf
Lynn McGuire <lmc@winsim.com>: Jan 08 03:03PM -0600

"Modern C++ Features – keyword `noexcept`"
http://arne-mertz.de/2016/01/modern-c-features-keyword-noexcept/
 
I can honestly say that I have never used anything like this.
 
Lynn
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 09 12:32AM +0100

On 1/8/2016 10:03 PM, Lynn McGuire wrote:
> "Modern C++ Features – keyword `noexcept`"
> http://arne-mertz.de/2016/01/modern-c-features-keyword-noexcept/
 
> I can honestly say that I have never used anything like this.
 
It's only the last year (or two?) that all 2 relevant compilers for me
support pure `noexcept`. Previously I used a macro CPPX_NOEXCEPT defined
as `noexcept` or `throw()` depending on the compiler. That technique
left no room for conditional no-throw.
 
I think the apparently useless complication of a conditional no-throw
thing is probably in support of the misguided decision to not require
move constructors to be no-throw, which presents a problem for a
std::vector (the example used in the original paper by Dave Abrahams &
one other) when it needs to reallocate and move the old items.
 
As a result of that decision, std::vector is now not exception safe,
which is a bit nasty! :(
 
 
Cheers,
 
- Alf
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: