From: Mathias Gaunard on
On Jun 30, 9:14 am, "Alf P. Steinbach /Usenet" <alf.p.steinbach
+use...(a)gmail.com> wrote:

> Point 8 "importing a namespace in implementation files is usually not a good
> idea". Hm. Again it is a matter of context. In a "complex" system (spaghetti)
> using qualified names everywhere might reduce some symptoms and reduce time
> wasted on bug-hunting. But otherwise, readability reduces programmers' time,
> i.e. improves programmer efficiency. Some people do maintain that to their eyes
> std::cout is more readable than cout, they swallow their colons for breakfast
> every day & enjoy it. Not for me though; if one is not going to use namespaces
> as they were intended, including "using", then just stick to C prefixes. :-)

Actually, it could be argued that importing a namespace anywhere is
*never* a good idea, because unqualified calls in C++ are extremely
dangerous due to ADL.
I know for example that there are a lot of subtle bugs in Boost that
are caused by this.


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

From: Edward Diener on
On 6/30/2010 3:55 AM, Kaba wrote:
> Edward Diener wrote:
>> On 6/28/2010 9:32 PM, Johannes Schaub (litb) wrote:
>>> I would also not recommend using a "size_t" to store an offset containing
>>> "12" - i think it's bad to use "unsigned" just to signify a quantity is
>>> unsigned.
>>
>> 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 ?
>
> My opinion is also that unsigned should not be used for integer
> quantities. My reasoning goes as follows:
>
> 1. Robustness
>
> 1a) The neighborhood of zero is perhaps the most used of all integer
> values.

You seem to be claiming that comparing an unsigned to 0 or setting an
unsigned to 0 does not work. Care to explain why ? Maybe I have missed
something deep in C++. The last I heard was that the range of an
unsigned is 0 to some positive number, that 0 is a perfectly valid value
for an unsigned number, and that one never has to specify 0U to make it so.

> 1b) It is easy to get buggy computations off by few, leading to negative
> values. Negative values then get wrapped to positive values, and these
> can't be taken as a bug, because there are no invalid values.
> 1c) More robust programs are created by allowing for negative values so
> that they can be used to detect bugs. You can also do this with unsigned
> values by allocating the last half to this purpose, but that does not
> correspond with logic anymore.

So for non-negative values you use a type which can be negative and then
you check to see if you have a bug if something does not work by seeing
if any of the values are negative ? This is surely not the way I
program. I use unit tests instead with possibly random input.

>
> 2. Preservation of information
>
> 2a) Unsigned<->signed conversions are, in general, lossy.

On which CPUs is this supposed to occur.

> 2b) The only way to deal with these conversions are to avoid them. Thus
> you should either use only unsigned or signed.
> 2c) When used to model the ring of integers, unsigned integers have
> robustness issues, as explained in 1), and they can't, by definition,
> deal with negative integers.
> 2d) Therefore signed integers are the proper model for the ring of
> integers.

If I wanted to model a ring of integers I would not include a
non-negative value in that ring to begin with.

>
> 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.

>
> 4. Floating point analogue
>
> One can imagine an unsigned floating point type by stripping off the
> sign bit, and perhaps giving an additional bit to the mantissa. Such a
> type would have similar problems as listed here for the integers.
> Interestingly, people don't seem to have anxiety over this lost bit,
> although the situation is exactly as with the integers.

One can imagine the grass is blue but that does not mean it happens, nor
does it have any relevance to the color of the sky.

>
> 5. Summary
>
> I think all of the previous can be summarized as follows. Most of the
> time we are interested in modeling the ring of integers (math Z), even
> though we'd only use the non-negative values. This is because values are
> rarely simply stored: rather, they are used for further computations. We
> want to (or most often implicitly) think of all operations (+, -, *) as
> if we were working in Z. Because of finite storage, this does not hold
> on the limits. But it does hold most of the time, that is, when we work
> on the neighborhood of zero. Being able to work in this neighborhood
> safely and cleanly is important for bug-free programs. This is what
> signed integers offer over unsigned integers.
>
> The story for the imaginary unsigned floating point type would be
> similar, now discussing reals and non-negative reals.

Your arguments don't even begin to convince me. Only 1c has any
practical value but since I don't program/debug the way you do, I can
forgo such an exotic reason.

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

From: Edward Diener on
On 6/30/2010 3:58 AM, joe wrote:
> Edward Diener wrote:
>> On 6/28/2010 9:32 PM, Johannes Schaub (litb) wrote:
>>> 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 i really don't agree with is depending on things included
>>> by other 3rd party headers.
>>>
>>> I would also not recommend using a "size_t" to store an offset
>>> containing "12" - i think it's bad to use "unsigned" just to signify
>>> a quantity is unsigned.
>>
>> 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 ?
>
> You just opened up the can of worms that was a long thread or 3 last
> month! From what I gathered, it is personal preference though each
> "side" will try to convince the other that they are "right".

Sorry I missed the argument. I will forgo any further comments or
replies on this as it was evidently hashed out by others and I don't
want to continue arguing something which is not really apropos for this
thread.



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

From: Seungbeom Kim on
On 2010-06-30 00:55, Kaba wrote:
>
> My opinion is also that unsigned should not be used for integer
> quantities. My reasoning goes as follows:
>
> 1. Robustness
[...]
> 2. Preservation of information
[...]
> 3. Consistency and traps
[...]
> 4. Floating point analogue
>
> One can imagine an unsigned floating point type by stripping off the
> sign bit, and perhaps giving an additional bit to the mantissa. Such a
> type would have similar problems as listed here for the integers.
> Interestingly, people don't seem to have anxiety over this lost bit,
> although the situation is exactly as with the integers.

Probably because floating-point types already have wider ranges,
and probably because people already take it as a matter of fact
that floating-point values are not accurate.

An IEEE single precision floating-point format can already represent
24 bits of mantissa, i.e. about 7 decimal digits, which is enough for
many purposes, and adding one bit doesn't change things that much:
it doesn't make it capable of representing 1/3 or 0.1 exactly anyway.
And that's "single" precision (usually the 4-byte type "float");
an IEEE double precision floating-point format (usually the 8-byte type
"double") has 53 bits of mantissa, i.e. about 16 decimal digits.
And the inexactness stays the same.

Things might have been different for integers in the old 8-bit and
16-bit days, where the space was limited, out of which every possible
bit had to be utilized. 32767 and 65536 make a big difference as
the highest representable integer. And no inexactness is tolerable.
That's probably why size_t had to be unsigned. In the 64-bit days,
who cares if size_t cannot represent more than 2^63-1 instead of 2^64-1?

> 5. Summary
>
> I think all of the previous can be summarized as follows. Most of the
> time we are interested in modeling the ring of integers (math Z), even
> though we'd only use the non-negative values. This is because values are
> rarely simply stored: rather, they are used for further computations. We
> want to (or most often implicitly) think of all operations (+, -, *) as
> if we were working in Z. Because of finite storage, this does not hold
> on the limits. But it does hold most of the time, that is, when we work
> on the neighborhood of zero. Being able to work in this neighborhood
> safely and cleanly is important for bug-free programs. This is what
> signed integers offer over unsigned integers.

The points are all valid. However, it is also "given" that size_t is
unsigned, and so is size_type for the standard containers. Employing
signed integers for sizes and counts inevitably leads to mixing them
with unsigned integers which are given by sizeof() and container.size(),
and a flood of corresponding warnings:

for (int i = 0; i < v.size(); ++i) ... // warning!

for (unsigned i = 0; i < v.size(); ++i) ... // no warning
// or better(?), use std::vector<...>::size_type

I'm curious how you deal with this issue if you're diligently following
your own arguments.

--
Seungbeom Kim

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

From: Hakusa on
On Jun 30, 9:01 am, Seungbeom Kim <musip...(a)bawi.org> wrote:
> On 2010-06-29 13:31, Hak...(a)gmail.com wrote:
>
>
>
> > I disagree with your classification of magic numbers. By what i see in
> > your slide:
> > f(60); // using magic number
> > but:
> > const int x = 60;
> > f(x); // Suddenly OK.
> > In my mind, 60 does not stop being magic just because it's named. The
> > question of where this number came from is still unanswered.
>
> You should name the variable appropriately. 'ssp_flags_offset' and
> 'challenge_offset' in the example from the OP's slides are named so,
> and 'x' is not.

That avoids the point. x is an appropriate name for an example where a
variable is needed, but does nothing. If x is a bad name, so if f, but
it is also appropriate for a function that does nothing in a small
example. Your critique is more of my example than a counter to my
argument that naming a variable does not remove its magic status. For
a more concrete example, say i have a c function taking in a void
pointer to an array, the size of each element in the array, and how
many elements are in it (as comes up in openGL, for example):
int array[22] = { /**/ };
c_function( array, 4, 22 );
Ignoring the 22, 4 is a magic number. If i were to improve it, using
the side:
int array[22] = { /**/ };
int sizeOfInt = 4;
c_function( array, sizeOfInt, 22 );
By my logic, 4 is still a magic number. Yes, it has a name, but where
that number came from is still unspecified.
int array[22] = { /**/ };
c_function( array, sizeof(int), 22 );
Now, even though the second argument is unnamed, i wouldn't consider
it magic.

Note: Please ignore the 22, it's not important for the example. Also,
please ignore that sizeof(int) isn't guaranteed to be 4; this was
important for the example, but not my point.


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