From: Jens Schmidt on
Kaba wrote:

> Edward Diener wrote:
>> > 2. Preservation of information
>> >
>> > 2a) Unsigned<->signed conversions are, in general, lossy.
>>
>> On which CPUs is this supposed to occur.
>
> The point is that the meaning of the value changes in conversion, for
> some values.

Examples:
-5 converted to unsigned is lossy.
32768 converted to signed is lossy for 16 bit arithmetic.

>> > 3. Consistency and traps
>> >
>> > 3a) Try to for-loop from positive n to zero using an unsigned integer
>> > index: it never finishes, although no negatives are conceptually used.
>> > 3b) Is there a difference between looping in the range [-4, 15] or [0,
>> > 15]? What about forward or backwards? It makes code more consistent to
>> > always use a signed integer, and you will never have to think things
>> > like 3a).
>>
>> Your 3a is imaginary since of course it finishes:
>>
>> unsigned int x;
>> for (x = 50 /* or any valid non-negative value */; x != 0; --x ) { /* do
>> something with x */ }
>>
>> Pray tell me why the above "for loop" never finishes.

The problem here is not non-termination, but x has a value one off in
the body. You usually don't want to do something with x, but with x-1.

> Your loop does finish, but it only iterates in the range [1, 50]: the
> problem is to iterate in [0, 50].

For the usual size==one more than the largest index, the problem is to
interate in [0, 49].
--
Greetings,
Jens Schmidt


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ian Collins on
On 06/29/10 08:51 AM, Olve Maudal wrote:
> At the NDC2010 conference, I gave a presentation where I demonstrated
> Solid C++ code by example:
>
> http://www.slideshare.net/olvemaudal/solid-c-by-example
>
> It would be great to have your opinion about the examples I present.
> Is this solid code, or can it be improved even further?

One thing that appears to have gone unmentioned is the frequent use of

std::vector<uint8_t>

I would have added a typedef, something like

typedef std::vector<uint8_t> raw_message;

to keep the noise down in the code and make the nature of the type clear.

Also given the focus on superfluous code, the use of "virtual" in the
derived classes is superfluous.

While I agree with most of the comments concerning superfluous
parentheses, and includes, I don't think they make the code less solid,
just more cluttered!

--
Ian Collins

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: nmm1 on
In article <MemdnW2mV_kdmrLRnZ2dnUVZ8mqdnZ2d(a)bt.com>,
Francis Glassborow <francis.glassborow(a)btinternet.com> wrote:
>Walter Bright wrote:
>> Edward Diener wrote:
>>> I have never understood such reasoning. If I have an integer value which
>>> I know must be unsigned, why would I not use an unsigned integer rather
>>> than a signed integer ?
>>
>> Because unsigned types tend to be 'sticky', i.e. (1 + 1u) is an
>> unsigned. This propagation of unsigned-ness is subtle and surprises even
>> experienced programmers.
>>
>> There was a long thread on this over on the D n.g., and I must say that
>> although I started from your position, I'm slowly moving towards using
>> unsigned only if you expect the values to have the high bit set.
>
>And there is the fact that unsigned is a strict modular arithmetic type
>whereas signed types have undefined behaviour when they overflow. That
>means that in high integrity processes checks for overflow potential
>must be made prior to evaluation of signed arithmetic.

No, it's not. Sorry. And that means that you ALSO have to check
before the evaluation with unsigned when you reach the places where
it is not modular - if your arithmetic model assumes modularity,
of course.

Division is the most obvious example. In modular 2^8 arithmetic,
507/169 is 3 and not 1, and not all operations have results (or have
unique ones, if they have). Checking afterwards will not detect all
breaches of modularity.

Also, practically, unsigned helps very little. Because (as someone
said), you normally expect characteristic zero integer semantics,
C-style unsigned integers merely change an overflow error (which is
trappable by a good compiler) into an undiagnosable wrong answer.
So you have to check anyway, if the compiler doesn't, and won't get
any help even from the best compilers.


Regards,
Nick Maclaren.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Francis Glassborow on
Jens Schmidt wrote:
> Kaba wrote:
>> Edward Diener wrote:
>>>> 2. Preservation of information
>>>>
>>>> 2a) Unsigned<->signed conversions are, in general, lossy.
>>> On which CPUs is this supposed to occur.
>> The point is that the meaning of the value changes in conversion, for
>> some values.
> Examples:
> -5 converted to unsigned is lossy.

But if the context is one where negative integers are meaningless (such as the length of an array) ?

> 32768 converted to signed is lossy for 16 bit arithmetic.

Worse, it has undefined behaviour

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Alf P. Steinbach /Usenet on
* Jens Schmidt, on 04.07.2010 10:46:
> Alf P. Steinbach wrote:
>
>> The key idea is to define the support lacking in the standard library,
> namely
>>
>> * a signed Size type (as ptrdiff_t), and a ditto Index type,
>>
>> * size, startOf and endOf functions where size() yields Size, and
>>
>> * to support those functions, automatic iterator type deduction.
>>
>> Then your example becomes
>>
>> for( Index i = 0; i< size( v ); ++i )
>>
>> which works no matter if v is a std::vector or a raw array or whatever,
>> and which also works just as nicely for a countdown,
>>
>> for( Index i = size( v ) - 1; i> 0; -- )
> If I read this correctly, you want "i>= 0" as comparison and "--i" as
> statement.

Yes.


> For countdown: why not just use a pattern like
> for_down (Index i = size (v); i> 0; --i)?
>
> Here for(a;b;c) d; expands as usual to
>
> a; while (b) { d; c; }
>
> and for_down(a;b;c) d; expands to
>
> a; while (b) { c; d; }
>
> (note the reversed order in the body). This pattern works with
> signed and unsigned types.

Well, extending the language with a 'for_down' construct isn't necessary.

The ordinary 'for' works OK for countdown with signed counter variable, and can with some effort be pressed into service also for unsigned counter variable. It's one of the problems with unsigned variables. It's not a significant problem with the 'for' loop itself, since the loop contstruct can be applied e.g. with signed variable.

Regarding 'for' loops what we need is, IMHO, a 'for_each'. The standard library's 'for_each' just doesn't cut it, in any way. Happily C++0x �6.5.4 defines such a loop, unfortunately called 'for' like the old one, but.


Cheers & hth.,

- Alf

--
blog at <url: http://alfps.wordpress.com>


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]