March 19, 2002 Unsigned | ||||
---|---|---|---|---|
| ||||
Does D handles unsigned integers in a better way than C/C++? Note that the following program is valid ISO C and ISO C++, and prints out -112 and -123 without problems. To me it seems trash. #include <stdio.h> unsigned int f(unsigned int n) { return n - 100U; } int main() { unsigned int u = -12; printf("the total is: %d\n", f(u)); printf("the total is: %d\n", f(-23)); return 0; } Ciao |
March 19, 2002 Re: Unsigned | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roberto Mariottini | "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a774v2$cjj$1@digitaldaemon.com... > Does D handles unsigned integers in a better way than C/C++? > Note that the following program is valid ISO C and ISO C++, and prints > out -112 and -123 without problems. To me it seems trash. What exactly do you expect? > > #include <stdio.h> > > unsigned int f(unsigned int n) > { > return n - 100U; > } > > int main() > { > unsigned int u = -12; > > printf("the total is: %d\n", f(u)); > printf("the total is: %d\n", f(-23)); > > return 0; > } This program is not "well-defined" ISO C. You've lied to printf, telling it to print a signed value ("%d"), while supplying an unsigned value. Try it again with "%u". (printf needs to be replaced with something type-safe. D doesn't plan to address this.) |
March 19, 2002 Re: Unsigned | ||||
---|---|---|---|---|
| ||||
Posted in reply to Richard Krehbiel | "Richard Krehbiel" <rich@kastle.com> ha scritto nel messaggio news:a77dur$j1u$1@digitaldaemon.com... > "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a774v2$cjj$1@digitaldaemon.com... > > Does D handles unsigned integers in a better way than C/C++? > > Note that the following program is valid ISO C and ISO C++, and prints > > out -112 and -123 without problems. To me it seems trash. > > What exactly do you expect? Something like this: > > > > #include <stdio.h> > > > > unsigned int f(unsigned int n) > > { > > return n - 100U; Here the subtraction should be internal within unsigned (being both operand unsigned). A negative result (i.e. carry flag set) should raise some exception. > > } > > > > int main() > > { > > unsigned int u = -12; This is a syntax/type error. > > > > printf("the total is: %d\n", f(u)); I agree that some substitute for printf is A MUST. > > printf("the total is: %d\n", f(-23)); Another syntax/type error. > > return 0; > > } > > This program is not "well-defined" ISO C. You've lied to printf, telling it > to print a signed value ("%d"), while supplying an unsigned value. Try it > again with "%u". It is 100% ISO-C standard. The fact it is malfunctioning is something programmer-related, not language related, as you stated. The fact is that in C and C++, int and unsigned are EXACTLY the same type for most operations. The example shown as an unsigned can be treated as a signed int, behaving perfectly the same. The only difference arise in comparison when <, >, <= or >= are involved. Note, anyway, that if (10u < -1) { printf ("I am a stupid language/compiler\n"); } else { printf ("I am a smart language/compiler\n"); } always shows how much C/C++ is stupid in handling unsignedness. Ciao |
March 19, 2002 Re: Unsigned | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roberto Mariottini | "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a77kqt$ov7$1@digitaldaemon.com... > "Richard Krehbiel" <rich@kastle.com> ha scritto nel messaggio news:a77dur$j1u$1@digitaldaemon.com... > > "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a774v2$cjj$1@digitaldaemon.com... > > > Does D handles unsigned integers in a better way than C/C++? > > > Note that the following program is valid ISO C and ISO C++, and prints > > > out -112 and -123 without problems. To me it seems trash. > > > > What exactly do you expect? > > Something like this: > > > > > > > #include <stdio.h> > > > > > > unsigned int f(unsigned int n) > > > { > > > return n - 100U; > > Here the subtraction should be internal within unsigned (being both > operand unsigned). A negative result (i.e. carry flag set) should raise some > exception. I use this property of unsigned'ed arithmetic (that of being modulo-UINT_MAX) a lot. If you're going to take it away, then replace it with something else. (I despise Java's lack of unsigned types and it's insistence that overflow and underflow throw exceptions.) > > > } > > > > > > int main() > > > { > > > unsigned int u = -12; > > This is a syntax/type error. How then should I represent the value that, when 12 is added to it, becomes zero? And keep in mind I'm still talking about modulo-2**32 math. (Visual Studio prints a warning about such signed/unsienged mismatches. I have resorted to turning them off.) > > > printf("the total is: %d\n", f(u)); > > I agree that some substitute for printf is A MUST. I have a sinister plan to write a macro language for D, a "DPP" if you will, that has full access to the D type system, and will allow writing a macro that offers a "print" statement that offers the following syntax: print "a = ", a, "b = ", b, "\n"; > The fact is that in C and C++, int and unsigned are EXACTLY the same type for most operations. You've got it right there. This is a consequence of the fact that, on most architectures, there is only a single set of machine instructions for arithmetic, used for both signed and unsigned types. The underlying machine can only do modulo-2**n arithmetic, and attempts to coerce it otherwise adds significant run-time overhead. Since D is supposed to be for high-performance systems work, it'll work this way too. Sorry. |
March 19, 2002 Re: Unsigned | ||||
---|---|---|---|---|
| ||||
Posted in reply to Richard Krehbiel | Richard Krehbiel wrote:
> "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message
>>>> unsigned int u = -12;
>>>>
>>This is a syntax/type error.
>>
>
> How then should I represent the value that, when 12 is added to it, becomes
> zero? And keep in mind I'm still talking about modulo-2**32 math.
>
> (Visual Studio prints a warning about such signed/unsienged mismatches. I
> have resorted to turning them off.)
This is an interesting point -- most compilers warn on
this. Under D, that means it's probably going to be
considered an error, because Walter is trying to
eliminate warnings. The warning-free C version is:
unsigned int u = (unsigned)-12;
and in D:
unsigned int u = cast(unsigned)-12;
Roberto, do you consider this a reasonable statement,
or erroneous? As Richard indicates, there's a long
history of using constructs like this. I had to do
it yesterday myself in converting an alignment to a
mask in memory management code.
-RB
|
March 19, 2002 Re: Unsigned | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roberto Mariottini | "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a77kqt$ov7$1@digitaldaemon.com... > The fact is that in C and C++, int and unsigned are EXACTLY the same type > for most operations. > The example shown as an unsigned can be treated as a signed int, behaving > perfectly the same. > The only difference arise in comparison when <, >, <= or >= are involved. The /, %, and >> behave differently as well as conversions to wider types or to floating point types. The reason that D does not change any of the semantics with operators, operator precedence, default integral promotions, etc., is because although many of the rules are byzantine, experienced C programmers have become very used to them. Subtly changing them will cause much grief in porting C code to D and porting C programmers to D <g> as wierd bugs will appear in formerly working code. |
March 20, 2002 Re: Unsigned | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> ha scritto nel messaggio news:a782ui$13q9$1@digitaldaemon.com... > > "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a77kqt$ov7$1@digitaldaemon.com... > > The fact is that in C and C++, int and unsigned are EXACTLY the same type > > for most operations. > > The example shown as an unsigned can be treated as a signed int, behaving > > perfectly the same. > > The only difference arise in comparison when <, >, <= or >= are involved. > > The /, %, and >> behave differently as well as conversions to wider types or > to floating point types. > > The reason that D does not change any of the semantics with operators, operator precedence, default integral promotions, etc., is because although > many of the rules are byzantine, experienced C programmers have become very > used to them. Subtly changing them will cause much grief in porting C code to D and porting C programmers to D <g> as wierd bugs will appear in formerly working code. I'm very disappointed with this. I've programmed C for more than ten years now, and C++ for nearly 10. And I NEVER use unsigneds, for I've learnt that it is a RIDICULOUS thing, that took me hours of bug tracking to find. Don't think you'll have much code to break, thoug, because people tend to not use unsigneds, like I do. I've seen a large quantity of code written by a large variety of people, and I think they can be divided in two kind of unsignedness usage: - People not using unsigned for "normal" operations, using it only in particular cases where it's necessary (like I do). - People using unsigned everywhere, in the firm belief the compiler will not accept code breaking the unsignedness (I often find unsigned functions parameters, and find people surprised when I tell them it assures nothing about signedness of the argument). For the first kind of people (that know what they do) a simple explaination on what changed in D and how to achieve the same functionality would be enough. For the second kind of people (the biggest part) no change in their programming life is needed, because they always thought it worked like this. Ciao. PS: if someone has some old C code that isn't worth changing, he can link it with D programs and let it be. |
March 20, 2002 Re: Unsigned | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roberto Mariottini | "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a79gcd$1rhf$1@digitaldaemon.com... > I'm very disappointed with this. > I've programmed C for more than ten years now, and C++ for nearly 10. > And I NEVER use unsigneds, for I've learnt that it is a RIDICULOUS thing, > that took me hours of bug tracking to find. > Don't think you'll have much code to break, thoug, because people tend to > not use unsigneds, like I do. Funny enough, my point is exactly the opposite: I always use unsigned ints where sign is not needed. I just don't understand why should I waste 2 billion of possible values, if they aren't used anyhow... > - People using unsigned everywhere, in the firm belief the compiler will > not > accept code breaking the unsignedness (I often find unsigned functions > parameters, > and find people surprised when I tell them it assures nothing about > signedness of > the argument). Most compilers issue warnings when you try to pass a signed value as an unsigned argument. This is much more reliable (and faster!) then checking the value in your function and raising an exception if it is negative. |
March 20, 2002 Re: Unsigned | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel Minayev | "Pavel Minayev" <evilone@omen.ru> ha scritto nel messaggio news:a79q0b$20bt$1@digitaldaemon.com... > "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a79gcd$1rhf$1@digitaldaemon.com... > > > I'm very disappointed with this. > > I've programmed C for more than ten years now, and C++ for nearly 10. > > And I NEVER use unsigneds, for I've learnt that it is a RIDICULOUS thing, > > that took me hours of bug tracking to find. > > Don't think you'll have much code to break, thoug, because people tend to > > not use unsigneds, like I do. > > Funny enough, my point is exactly the opposite: I always use unsigned ints where sign is not needed. I just don't understand why should I waste 2 billion of possible values, if they aren't used anyhow... They are used anyway. Every int can be used as unsigned without problems. In fact they are almost the same type. int i = MAX_INT + 13; // you can use the exact literal if you know it printf("%u", i); // prints out MAX_INT + 13 Using unsigned doesn't add anything to your programs. > > - People using unsigned everywhere, in the firm belief the compiler will > > not > > accept code breaking the unsignedness (I often find unsigned functions > > parameters, > > and find people surprised when I tell them it assures nothing about > > signedness of > > the argument). > > Most compilers issue warnings when you try to pass a signed value as an unsigned argument. This is much more reliable (and faster!) then checking the value in your function and raising an exception if it is negative. Yes, but what's a warning? An error? Not-an-error? (this recalls me fuzzy logic) D has no warnings. So it either: - stop with a compiler error - raise an exception Leaving it like it is (no warning AND no error AND no exception), is not the right way. Ciao |
March 20, 2002 Re: Unsigned | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roberto Mariottini | "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in message news:a7a0fl$23t5$1@digitaldaemon.com... > They are used anyway. Every int can be used as unsigned without problems. In fact they are almost the same type. > > int i = MAX_INT + 13; // you can use the exact literal if you know it printf("%u", i); // prints out MAX_INT + 13 > > Using unsigned doesn't add anything to your programs. Using unsigned states that this value can only be positive. This gives compiler the opportunity to warn programmer when he tries to pass a signed value where function expects an unsigned argument. And "they are used anyway" is wrong. Haven't you ever written anything like this? for (int i = 0; i < n; i++) ... Now, since i is signed, n can only be as large as 0x7fffffff (because otherwise the loop would never get executed). If it were declared as unsigned int, the entire range of values up to 0xffffffff can be used. I wonder, why use signed int where it is obviously unsigned? What benefits does it give? > D has no warnings. So it either: > > - stop with a compiler error > - raise an exception > > Leaving it like it is (no warning AND no error AND no exception), is not > the right way. Following this logic, D should also stop with a compiler error or raise an exception when passing a float as int argument, but it doesn't. Strict type-checking has its benefits, yet I don't like it much; guess I just had got too used to C freedom in type conversions... Exceptions are too costly to be taken seriously in such cases. Compiler error - could be, probably requiring an explicit cast. I'd prefer it to be as it is now, though (but this is just a personal point). |
Copyright © 1999-2021 by the D Language Foundation