This isn't a C++ question per se ... but rather, I'm posting this bcs I
want the answer from a C++ language perspective. Hope that makes sense.
I was reading Peter van der Linden's "Expert C Programming: Deep C
Secrets" and came across the following statement:
"Avoid unnecessary complexity by minimizing your use of unsigned types.
Specifically, don't use an unsigned type to represent a quantity just
because it will never be negative (e.g., "age" or "national_debt" )."
Admittedly, I minimize comments in my code. I use them when necessary
but try to limit them to one or two lines. I just don't like their
aesthetic affect in the source. I find the code much harder to read
littered with paragraphs of explanations.
I find the code easier to read when broken up with appropriate newlines
and small, short comments acting as headings.
So - that effectually means that I try my darndest to write
self-describing code. Shorter functions, self-explanatory names for
functions and variable names, etc. Sometimes exceessive commenting is
necessary, but as a whole, I tend to avoid it.
I'm really enjoying Peter's book, but I find this comment hard to
swallow considering that if an age or array index can never be negative
- I would want to illustrate that with an apporpriate choice of type -
namely, unsigned int.
Am I in the minority here? Is my predilection considered poor style?
I guess, from the compiler's standpoint ... using int everywhere is
more portable ... since comparison's against unsigned int can vary
between K&R and ANSI C.
I'm not incurring some type of performance penalty for such decisions
am I?
Thanks in advance,
-Luther
Feb 21 '06
26 36090
Alf P. Steinbach wrote: * Neil Cerutti: On 2006-02-21, Tomás <NU**@NULL.NULL > wrote: My first rule is to write "const" wherever I can. (except for return types).
My second rule is to write "unsigned" wherever I can.
I don't agree with that rule.
Thus I'll write:
unsigned GetDogAge(unsig ned const age) { return age * 7; }
What do you expect to happen if a client passes in an negative int?
The argument is not in the domain, yet the error has been rendered impossible to detect or recover from.
I don't disagree with your viewpoint regarding using or not using unsigned whenever possible; I think both are valid viewpoints, and as with indentation the main thing is to be consistent in one's choices.
However, I disagree with your reason!
With the unsigned argument a validity test might go like
assert( age < 200 ); // unsigned validity test.
With a signed argument the test might go like
assert( age >= 0 ); // signed validity test. assert( age < 200 ); // more signed validity test.
Now, first of all that demonstrates the "impossible to detect" is simply incorrect, and second, in my view it demonstrates a slight superiority for unsigned in this particular case, with respect to validity testing.
I believe he is talking about something like this:
#include <iostream>
using namespace std;
unsigned int GetDogAge(unsig ned int age)
{
return age * 7;
}
int main(int argc, char* argv[])
{
int t = -5;
unsigned int x = GetDogAge(t);
cout << x;
int y; cin >> y;
return 0;
}
------ Build started: Project: Playground, Configuration: Debug Win32
------
Compiling...
Playground.cpp
Linking...
Build log was saved at
"file://c:\src\Playgrou nd\Playground\D ebug\BuildLog.h tm"
Playground - 0 error(s), 0 warning(s)
---------------------- Done ----------------------
Build: 1 succeeded, 0 failed, 0 skipped
Output is, "4294967261 ."
It is an interesting point.
Daniel T. wrote: In article <11************ **********@f14g 2000cwb.googleg roups.com>, ro**********@gm ail.com wrote:
The great thing about unsigned is if the value can't be negative and you use signed then you always have to check it. Simply defining the type as unsigned gets rid of all that as well as documenting your domain. And the bad thing about unsigned is that if code would otherwise make the value negative, you can't check it. IE
void foo( unsigned s ) { // at this point s == 4294966272 // is it an error (s came in as -1024) or // does the client really want us to deal with that number? }
Bjarne Stroustrup says, "The unsigned integer types are ideal for uses that treat storage as a bit array. Using an unsigned instead of an int to gain one more bit to represent positive integers is almost never a good idea. Attempts to ensure that some values are positive by declaring variables unsigned will typically be defeated by the implicit conversion rules."
Sounds like a good excuse to write an unsigned_int class:
#include <boost/utility/enable_if.hpp>
#include <boost/numeric/conversion/converter.hpp>
#include <boost/type_traits/is_unsigned.hpp >
class unsigned_int{
unsigned int m_value;
public:
template <typename T>
unsigned_int(T const & rhs,
typename boost::enable_i f<
boost::is_unsig ned<T>,
void*::type = 0
)
{
// further features
// throws on overflow when T is bigger eg unsigned long
boost::numeric: :converter<unsi gned int,T> convert;
m_value = convert(rhs);
}
};
int main()
{
unsigned_int n1 = 1U;
unsigned_int n2 = static_cast<uns igned short>(1);
unsigned_int n3 = 1UL;
unsigned_int n4 = static_cast<uns igned int>(1);
unsigned_int n5 = 1; // Error!
}
reagrds
Andy Little
Daniel T. wrote: In article <11************ **********@f14g 2000cwb.googleg roups.com>, ro**********@gm ail.com wrote:
The great thing about unsigned is if the value can't be negative and you use signed then you always have to check it. Simply defining the type as unsigned gets rid of all that as well as documenting your domain. And the bad thing about unsigned is that if code would otherwise make the value negative, you can't check it. IE
void foo( unsigned s ) { // at this point s == 4294966272 // is it an error (s came in as -1024) or // does the client really want us to deal with that number? }
Bjarne Stroustrup says, "The unsigned integer types are ideal for uses that treat storage as a bit array. Using an unsigned instead of an int to gain one more bit to represent positive integers is almost never a good idea. Attempts to ensure that some values are positive by declaring variables unsigned will typically be defeated by the implicit conversion rules."
Sounds like a good excuse for an unsigned_int class ...
#include <boost/utility/enable_if.hpp>
#include <boost/numeric/conversion/converter.hpp>
#include <boost/type_traits/is_unsigned.hpp >
class unsigned_int{
unsigned int m_value;
public:
template <typename T>
unsigned_int(T const & rhs,
typename boost::enable_i f<
boost::is_unsig ned<T>,
void*::type = 0
)
{
// further features
// throws on overflow when T is bigger eg unsigned long
boost::numeric: :converter<unsi gned int,T> convert;
m_value = convert(rhs);
}
};
int main()
{
unsigned_int n1 = 1U;
unsigned_int n2 = static_cast<uns igned short>(1);
unsigned_int n3 = 1UL;
unsigned_int n4 = static_cast<uns igned int>(1);
unsigned_int n5 = 1; // Error!
}
reagrds
Andy Little
Daniel T. wrote: In article <11************ **********@f14g 2000cwb.googleg roups.com>, ro**********@gm ail.com wrote:
The great thing about unsigned is if the value can't be negative and you use signed then you always have to check it. Simply defining the type as unsigned gets rid of all that as well as documenting your domain. And the bad thing about unsigned is that if code would otherwise make the value negative, you can't check it. IE
void foo( unsigned s ) { // at this point s == 4294966272 // is it an error (s came in as -1024) or // does the client really want us to deal with that number? }
Bjarne Stroustrup says, "The unsigned integer types are ideal for uses that treat storage as a bit array. Using an unsigned instead of an int to gain one more bit to represent positive integers is almost never a good idea. Attempts to ensure that some values are positive by declaring variables unsigned will typically be defeated by the implicit conversion rules."
Sounds like a good excuse to write an unsigned_int class:
#include <boost/utility/enable_if.hpp>
#include <boost/numeric/conversion/converter.hpp>
#include <boost/type_traits/is_unsigned.hpp >
class unsigned_int{
unsigned int m_value;
public:
template <typename T>
unsigned_int(T const & rhs,
typename boost::enable_i f<
boost::is_unsig ned<T>,
void*::type = 0
)
{
// further features
// throws on overflow when T is bigger eg unsigned long
boost::numeric: :converter<unsi gned int,T> convert;
m_value = convert(rhs);
}
};
int main()
{
unsigned_int n1 = 1U;
unsigned_int n2 = static_cast<uns igned short>(1);
unsigned_int n3 = 1UL;
unsigned_int n4 = static_cast<uns igned int>(1);
unsigned_int n5 = 1; // Error!
}
reagrds
Andy Little
a...@servocomm. freeserve.co.uk wrote:
Sorry
Sorry
Sorry for posting 3 times. Browser hung up
regards
Andy Little
* ro**********@gm ail.com: Alf P. Steinbach wrote: * Neil Cerutti: On 2006-02-21, Tomás <NU**@NULL.NULL > wrote: My first rule is to write "const" wherever I can. (except for return types).
My second rule is to write "unsigned" wherever I can. I don't agree with that rule.
Thus I'll write:
unsigned GetDogAge(unsig ned const age) { return age * 7; } What do you expect to happen if a client passes in an negative int?
The argument is not in the domain, yet the error has been rendered impossible to detect or recover from. I don't disagree with your viewpoint regarding using or not using unsigned whenever possible; I think both are valid viewpoints, and as with indentation the main thing is to be consistent in one's choices.
However, I disagree with your reason!
With the unsigned argument a validity test might go like
assert( age < 200 ); // unsigned validity test.
With a signed argument the test might go like
assert( age >= 0 ); // signed validity test. assert( age < 200 ); // more signed validity test.
Now, first of all that demonstrates the "impossible to detect" is simply incorrect, and second, in my view it demonstrates a slight superiority for unsigned in this particular case, with respect to validity testing.
I believe he is talking about something like this:
[snip] int t = -5; unsigned int x = GetDogAge(t);
Yes, that would be caught by the validity test for unsigned formal arg,
assert( age < 200 );
Cheers,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
LuB wrote: This isn't a C++ question per se ... but rather, I'm posting this bcs I want the answer from a C++ language perspective. Hope that makes sense.
I was reading Peter van der Linden's "Expert C Programming: Deep C Secrets" and came across the following statement:
"Avoid unnecessary complexity by minimizing your use of unsigned types. Specifically, don't use an unsigned type to represent a quantity just because it will never be negative (e.g., "age" or "national_debt" )."
Admittedly, I minimize comments in my code. I use them when necessary but try to limit them to one or two lines. I just don't like their aesthetic affect in the source. I find the code much harder to read littered with paragraphs of explanations.
I find the code easier to read when broken up with appropriate newlines and small, short comments acting as headings.
So - that effectually means that I try my darndest to write self-describing code. Shorter functions, self-explanatory names for functions and variable names, etc. Sometimes exceessive commenting is necessary, but as a whole, I tend to avoid it.
I'm really enjoying Peter's book, but I find this comment hard to swallow considering that if an age or array index can never be negative - I would want to illustrate that with an apporpriate choice of type - namely, unsigned int.
Am I in the minority here? Is my predilection considered poor style?
I guess, from the compiler's standpoint ... using int everywhere is more portable ... since comparison's against unsigned int can vary between K&R and ANSI C.
I'm not incurring some type of performance penalty for such decisions am I?
Thanks in advance,
-Luther
It's like driving on the left or driving on the right. It's basically
an
arbitrary choice (now that we drive cars), it's just good if everyone
makes the same arbitrary choice. That is if there's more than
just you on the road, which is analagous to maintaining
existing code or heavily using libraries written by others.
Many compilers generate (to me helpful) warnings if you do a, <, <=, >= comparison between a signed and unsigned.
Many also generate (to me useless) warnings if you do a
== or != comparison between a signed and unsigned. So,
you can end up with alot of static_casts to get rid of the
warnings.
For some reason, if an unsigned type is used in an expression
where it has to be implicitly converted to a larger type, it
will be converted to a signed larger type. As far as I can
see, this rule has no practical effect, other than to give
some compilers an excuse to generate unnecessary
warnings. (I guess it could change the results when
using bitwise ops on variables of different sizes, which
to me is a bad idea anyway.) So, that's one reason to prefer
signed. But, like you, I prefer to use unsigned for variables that
should always be nonnegative, to make the intent clear.
Daniel T. wrote: In article <11************ **********@f14g 2000cwb.googleg roups.com>, ro**********@gm ail.com wrote:
The great thing about unsigned is if the value can't be negative and you use signed then you always have to check it. Simply defining the type as unsigned gets rid of all that as well as documenting your domain.
And the bad thing about unsigned is that if code would otherwise make the value negative, you can't check it. IE
Surely overflow and underflow are a problem with both signed and unsigned?
These are often situations where you are unable to check validity
without domain specific knowledge - I don't see how signed unsigned vary
in that regard.
Ben Pope
--
I'm not just a number. To many, I'm known as a string...
LuB wrote: This isn't a C++ question per se ... but rather, I'm posting this bcs I want the answer from a C++ language perspective. Hope that makes sense.
I was reading Peter van der Linden's "Expert C Programming: Deep C Secrets" and came across the following statement:
"Avoid unnecessary complexity by minimizing your use of unsigned types. Specifically, don't use an unsigned type to represent a quantity just because it will never be negative (e.g., "age" or "national_debt" )."
Admittedly, I minimize comments in my code. I use them when necessary but try to limit them to one or two lines. I just don't like their aesthetic affect in the source. I find the code much harder to read littered with paragraphs of explanations.
I find the code easier to read when broken up with appropriate newlines and small, short comments acting as headings.
So - that effectually means that I try my darndest to write self-describing code. Shorter functions, self-explanatory names for functions and variable names, etc. Sometimes exceessive commenting is necessary, but as a whole, I tend to avoid it.
Self-explanatory names are good.
I'm really enjoying Peter's book, but I find this comment hard to swallow considering that if an age or array index can never be negative - I would want to illustrate that with an apporpriate choice of type - namely, unsigned int.
Why would you want to illustrate it with an appropriate choice of type?
I would want to illustrate it with a self-explanatory name.
Am I in the minority here? Is my predilection considered poor style?
I guess, from the compiler's standpoint ... using int everywhere is more portable ... since comparison's against unsigned int can vary between K&R and ANSI C.
I'm not incurring some type of performance penalty for such decisions am I?
This question comes up regularly. Search the history of the newsgroup
and you will find plenty of discussion. But I am slightly surprised to
see this thread get to nearly 20 posts (as far as I can see so far)
without anyone mentioning the subtraction issue.
Personally, I do not accept that argument for unsigned as documentation
to mean "negative values make no sense here". The variable name (age,
buffer_size, radius) serves that purpose. Comparison with const is not
valid. const is useful because it is enforced by the compiler. unsigned
is not enforced. -1 years does not make sense for age, but neither does
4294967295 years. At best, using unsigned has only documented one end
of your range. And since the variable name has already achieved that,
you haven't gained anything.
But that's not the only reason I don't use unsigned for these sort of
quantities. In general, subtracting one person's age from another in
the real world yields a signed result but in C++ subtracting one
unsigned quantity from another yields an unsigned result.
<quote Kaz Kylheku (in post number 28 as I write this)> http://groups.google.co.uk/group/com...236f41f9de66f8
Thus code like if (buffer_space - requested_paylo ad > header_size)
is broken if unsigned integers are used, and there was no prior check
that the requested_paylo ad isn't larger than the buffer.
</quote>
Both signed and unsigned arithmetic in C++ behave just like real world
integer arithmetic until you reach the minimum and maximum values for
those types. The difference is that for signed, the correlation between
the real world and C++ breaks down at + or - a very big number, whereas
for unsigned, the correlation between the real world and C++ breaks
down at zero and a (different) very big number.
In other words, if I use unsigned, I am very close to the edge of the
domain in which C++ arithmetic corresponds to the real world. If I use
signed, I am comfortably in the middle of that domain and the
extremities where I have to start coding for special cases are far, far
away from any number that I am likely to ever want to use for an age or
a length or a size, or I am likely to ever end up with by doing
arithmetic with those quantities.
Gavin Deane
Gavin Deane wrote: But that's not the only reason I don't use unsigned for these sort of quantities. In general, subtracting one person's age from another in the real world yields a signed result but in C++ subtracting one unsigned quantity from another yields an unsigned result.
<quote Kaz Kylheku (in post number 28 as I write this)> http://groups.google.co.uk/group/com...236f41f9de66f8
Thus code like if (buffer_space - requested_paylo ad > header_size) is broken if unsigned integers are used, and there was no prior check that the requested_paylo ad isn't larger than the buffer.
</quote>
That's a very good point.
Both signed and unsigned arithmetic in C++ behave just like real world integer arithmetic until you reach the minimum and maximum values for those types. The difference is that for signed, the correlation between the real world and C++ breaks down at + or - a very big number, whereas for unsigned, the correlation between the real world and C++ breaks down at zero and a (different) very big number.
In other words, if I use unsigned, I am very close to the edge of the domain in which C++ arithmetic corresponds to the real world. If I use signed, I am comfortably in the middle of that domain and the extremities where I have to start coding for special cases are far, far away from any number that I am likely to ever want to use for an age or a length or a size, or I am likely to ever end up with by doing arithmetic with those quantities.
In an ideal world, we would probably all do range checking more often
than we do.
I always say you make your own luck, with signed types you're more lucky!
Ben Pope
--
I'm not just a number. To many, I'm known as a string... This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: MiniDisc_2k2 |
last post by:
Okay, here's a question about the standard. What does it say about
unsigned/signed mismatches in a comparison statement:
char a = 3;
unsigned char b = 255;
if (a<b)
Now what's the real answer here? If a is converted to unsigned, then b>a.
But, if b is converted to signed,then a>b. What's the correct coversion
(what is the compiler supposed to do?)
|
by: Siemel Naran |
last post by:
Hi. Is there a way to convert the type signed int to the type unsigned int,
char to unsigned char, signed char to unsigned char, and so on for all the
fundamental integer types? Something like
template <>
struct to_unsigned<signed int> : public std::unary_function<signed int,
unsigned int>
{
unsigned int operator()(signed int x) const { return x; }
};
|
by: Fred Ma |
last post by:
Hello,
I've been trying to clear up a confusion about
integer promotions during expression evaluation.
I've checked the C FAQ and C++ FAQ (they are
different languages, but I was hoping one would
clear up the confusion), as well as googling
groups and the web.
The confusion is that for a binary operator,
|
by: dam_fool_2003 |
last post by:
For int data type the default range starts from signed to unsigned. If
we don't want negative value we can force an unsigned value. The same
goes for long also.
But I don't understand why we have signed char which is -256. Does it
means that we can assign the same ASCII value to both signed and
unsigned. That means the ASCII value can be represented with a type of
signed char and also unsigned char?
For example
int main(void)
{
|
by: tinesan |
last post by:
Hello fellow C programmers,
I'm just learning to program with C, and I'm wondering what the
difference between signed and unsigned char is. To me there seems to
be no difference, and the standard doesn't even care what a normal char
is (because signed and unsigned have equal behavior).
For example if someone does this:
unsigned char a = -2; /* or = 254 */
| |
by: Hanzac Chen |
last post by:
Hi,
I don't understand why this could happen?
The Code 1 will output `fff9'
and the Code 2 will output `1'
How could the `mod 8' not have effect?
/* Code 1 */
#include <stdio.h>
#include <stdlib.h>
|
by: =?iso-8859-2?B?SmFuIFJpbmdvuQ==?= |
last post by:
Hello everybody,
this is my first post to a newsgroup at all.
I would like to get some feedback on one proposal I am thinking about:
--- begin of proposal ---
Proposal to add
signed/unsigned modifier to class declarations
to next revision of C++ programming language
|
by: somenath |
last post by:
Hi All,
I am trying to undestand "Type Conversions" from K&R book.I am not
able to understand the
bellow mentioned text
"Conversion rules are more complicated when unsigned operands are
involved. The problem
is that comparisons between signed and unsigned values are machine-
dependent, because
they depend on the sizes of the various integer types. For example,
suppose that int is 16 bits
|
by: Kislay |
last post by:
Consider the following code snippet
unsigned int i=10;
int j= - 2; // minus 2
if(i>j)
cout<<"i is greater";
else
cout<<"j is greater";
Since i is unsigned , j is greater . I know why , but vaguely . Can
|
by: Juha Nieminen |
last post by:
I was once taught that if some integral value can never have negative
values, it's a good style to use an 'unsigned' type for that: It's
informative, self-documenting, and you are not wasting half of the value
range for values which you will never be using.
I agreed with this, and started to always use 'unsigned' whenever
negative values wouldn't make any sense. I did this for years.
However, I slowly changed my mind: Doing this often...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
| |
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
| |
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |