[c-prog] Re: integer promotions
--- In c-prog@yahoogroups.com, Pedro Izecksohn [EMAIL PROTECTED] wrote: OK, I wrote a bad piece of code. Let me try to codify my problem again: #include limits.h #include stdio.h int main (void) { unsigned short int a; unsigned long long int b, c; a = USHRT_MAX; b = (a*a); c = ((unsigned int)a*(unsigned int)a); printf (Why %llx != %llx ?\n, b, c); return 0; } When I execute it I get: Why fffe0001 != fffe0001 ? b is wrong. I see what you are saying - ignoring what C says should happen, and assuming USHRT_MAX = 0x, you have: b = a * a = 0x * 0x = 0xfffe0001 So why do you get 0xfffe0001? Good question - my guess is that at some point the result is a negative (ie. signed) value, and this gets sign-extended. For example, if you have -1 as a signed short, and want to convert it to a signed int, the result should still be -1. But if you like at these values in hex, you have 0x (short) becoming 0x (int), which looks similar to what has happened to b in your program. But hopefully some can quote the relevant bit of the Standard. John
[c-prog] Re: integer promotions
Sorry- must have got up too early: But if you like at these values in hex 'like' - 'look' But hopefully some can quote the relevant bit of the Standard. 'some' - 'someone'
[c-prog] Ahmed Shabana wants to chat
--- Ahmed Shabana wants to stay in better touch using some of Google's coolest new products. If you already have Gmail or Google Talk, visit: http://mail.google.com/mail/b-a0c3cfa5cd-0bb9fda036-f3957799f9ad4eee You'll need to click this link to be able to chat with Ahmed Shabana. To get Gmail - a free email account from Google with over 2,800 megabytes of storage - and chat with Ahmed Shabana, visit: http://mail.google.com/mail/a-a0c3cfa5cd-0bb9fda036-110de22694 Gmail offers: - Instant messaging right inside Gmail - Powerful spam protection - Built-in search for finding your messages and a helpful way of organizing emails into conversations - No pop-up ads or untargeted banners - just text ads and related information that are relevant to the content of your messages All this, and its yours for free. But wait, there's more! By opening a Gmail account, you also get access to Google Talk, Google's instant messaging service: http://www.google.com/talk/ Google Talk offers: - Web-based chat that you can use anywhere, without a download - A contact list that's synchronized with your Gmail account - Free, high quality PC-to-PC voice calls when you download the Google Talk client Gmail and Google Talk are still in beta. We're working hard to add new features and make improvements, so we might also ask for your comments and suggestions periodically. We appreciate your help in making our products even better! Thanks, The Google Team To learn more about Gmail and Google Talk, visit: http://mail.google.com/mail/help/about.html http://www.google.com/talk/about.html (If clicking the URLs in this message does not work, copy and paste them into the address bar of your browser).
[c-prog] Nested structure segmentation fault ??
#includestdio.h #includestring.h struct sub { char name[100]; }; struct maiN { struct sub *s1; int c; }; int main() { struct maiN s0; strcpy(s0.s1-name,hi man ); return 0; } It compile so good but when run get segmentation fault CAN ANY ONE TOLD ME WHY ??
[c-prog] Re: Nested structure segmentation fault ??
--- In c-prog@yahoogroups.com, Ahmed Shabana [EMAIL PROTECTED] wrote: struct maiN s0; strcpy(s0.s1-name,hi man ); but when run get segmentation fault You haven't initialised s0, so s1 could be pointing anywhere.
Re: [c-prog] Re: integer promotions
hello, If you multiply two unsigned shorts together, you'll get an unsigned short, or, if the number is to big, it'll overflow; you'll want to use an int. Hope that helps somewhat, Thanks, Tyler Littlefield email: [EMAIL PROTECTED] web: tysdomain-com Visit for quality software and web design. skype: st8amnd2005 - Original Message - From: Pedro Izecksohn To: c-prog@yahoogroups.com Sent: Saturday, November 22, 2008 10:14 PM Subject: [c-prog] Re: integer promotions --- Tyler Littlefield wrote: and you want... what exactly? I did not express myself well. Let me reformulate my question: --- Paul Herring wrote: Here you're multiplying two shorts. What is the type of result of a multiplication of two unsigned short integers? In other words: Being: unsigned short int a, b; T result; //... result = (a*b); What should be the type T? When running my previous code the result is: Why fffe0001 != fffe0001 ? Is this result a compiler's bug? [Non-text portions of this message have been removed]
[c-prog] Re: Nested structure segmentation fault ??
--- In c-prog@yahoogroups.com, David Hamill [EMAIL PROTECTED] wrote: John wrote: You haven't initialised s0, so s1 could be pointing anywhere. But my money would be on it having the value zero. I.e. an uninitialised pointer is a null pointer. I don't know if this is in the standard It isn't, and as C compilers generally aim to generate 'tight' code, they don't do anything that they don't have to. So the value of the pointer will be whatever was in memory before, which might be 0, but it very much depends on your compiler/OS/what happened a bit earlier etc.
[c-prog] Re: Nested structure segmentation fault ??
--- In c-prog@yahoogroups.com, John Matthews [EMAIL PROTECTED] wrote: So the value of the pointer will be whatever was in memory before, which might be 0, but it very much depends on your compiler/OS/what happened a bit earlier etc. Adding a printf() in the OP's code, using gcc under linux: $ a.out s0.s1 = 0xa75ff4 Segmentation fault $ a.out s0.s1 = 0x24eff4 Segmentation fault Hope you didn't put too much money on it :-)
Re: [c-prog] Re: Nested structure segmentation fault ??
On Sun, Nov 23, 2008 at 1:19 PM, John Matthews [EMAIL PROTECTED] wrote: --- In c-prog@yahoogroups.com, John Matthews [EMAIL PROTECTED] wrote: So the value of the pointer will be whatever was in memory before, which might be 0, but it very much depends on your compiler/OS/what happened a bit earlier etc. Adding a printf() in the OP's code, using gcc under linux: $ a.out s0.s1 = 0xa75ff4 Segmentation fault $ a.out s0.s1 = 0x24eff4 Segmentation fault Hope you didn't put too much money on it :-) okay what is the solution of this problem ???/ HOW can I assign the variable which called name
Re: [c-prog] Nested structure segmentation fault ??
On Sun, Nov 23, 2008 at 4:48 AM, Ahmed Shabana [EMAIL PROTECTED] wrote: #includestdio.h #includestring.h struct sub { char name[100]; }; struct maiN { struct sub *s1; int c; }; sub *s1 is a pointer inside maiN int main() { struct maiN s0; strcpy(s0.s1-name,hi man ); You create an instance of maiN but s1 has not been initialized (need to allocate memory for it). You try to write data into s1 but you're not allowed to yet. -- Brett In the rhythm of music a secret is hidden; If I were to divulge it, it would overturn the world. -- Jelaleddin Rumi
[c-prog] Re: Nested structure segmentation fault ??
--- In c-prog@yahoogroups.com, Ahmed Shabana [EMAIL PROTECTED] wrote: okay what is the solution of this problem ???/ HOW can I assign the variable which called name Example: int main() { struct sub sub0; struct maiN s0; s0.s1 = sub0; s0.c = 42; strcpy(s0.s1-name,hi man ); printf(name: %s\nvalue: %d\n, s0.s1-name, s0.c); return 0; }
Re: [c-prog] Nested structure segmentation fault ??
On Sun, Nov 23, 2008 at 2:10 PM, Brett McCoy [EMAIL PROTECTED] wrote: On Sun, Nov 23, 2008 at 4:48 AM, Ahmed Shabana [EMAIL PROTECTED] wrote: #includestdio.h #includestring.h struct sub { char name[100]; }; struct maiN { struct sub *s1; int c; }; sub *s1 is a pointer inside maiN int main() { struct maiN s0; strcpy(s0.s1-name,hi man ); You create an instance of maiN but s1 has not been initialized (need to allocate memory for it). You try to write data into s1 but you're not allowed to yet. I tried to type struct sub s1 inside the main and outside the main and they gave me the same result
[c-prog] Re: Nested structure segmentation fault ??
Do you need to use a pointer in the maiN structure? If you don't, your program becomes simpler: #include stdio.h #include string.h struct sub { char name[100]; }; struct maiN { struct sub s1; int c; }; int main(void) { struct maiN s0; s0.c = 42; strcpy(s0.s1.name,hi man ); printf(name: %s\nvalue: %d\n, s0.s1.name, s0.c); return 0; }
Re: [c-prog] Re: Nested structure segmentation fault ??
On Sun, Nov 23, 2008 at 12:30 PM, John Matthews [EMAIL PROTECTED] wrote: --- In c-prog@yahoogroups.com, John Matthews [EMAIL PROTECTED] wrote: --- In c-prog@yahoogroups.com, Ahmed Shabana UnlimitedEng@ wrote: okay what is the solution of this problem ???/ HOW can I assign the variable which called name Example: int main() { struct sub sub0; struct maiN s0; s0.s1 = sub0; s0.c = 42; strcpy(s0.s1-name,hi man ); printf(name: %s\nvalue: %d\n, s0.s1-name, s0.c); return 0; } ...or alternatively use dynamic memory allocation: Or get rid of the problem altogether so you don't have to 'remember' to do anything, and change the containing struct: struct maiN { struct sub s1; /* changed from pointer to the object itself */ int c; }; Making the code in the OP work as expected (changing the redirection of course): int main() { struct maiN s0; strcpy(s0.s1.name,hi man ); return 0; } -- PJH http://shabbleland.myminicity.com/tra
[c-prog] Re: Nested structure segmentation fault ??
--- In c-prog@yahoogroups.com, John Matthews [EMAIL PROTECTED] wrote: --- In c-prog@yahoogroups.com, Ahmed Shabana UnlimitedEng@ wrote: okay what is the solution of this problem ???/ HOW can I assign the variable which called name Example: int main() { struct sub sub0; struct maiN s0; s0.s1 = sub0; s0.c = 42; strcpy(s0.s1-name,hi man ); printf(name: %s\nvalue: %d\n, s0.s1-name, s0.c); return 0; } ...or alternatively use dynamic memory allocation: #include malloc.h int main(void) { struct maiN s0; s0.s1 = malloc(sizeof *s0.s1); /* should check not NULL */ s0.c = 42; etc.
Re: [c-prog] Re: Nested structure segmentation fault ??
John wrote: You haven't initialised s0, so s1 could be pointing anywhere. But my money would be on it having the value zero. I.e. an uninitialised pointer is a null pointer. I don't know if this is in the standard, but it would be a sensible thing for a compiler to do, as null pointer dereferencing is trivial to detect at runtime. David
Re: [c-prog] Re: Nested structure segmentation fault ??
1rst Thanks too much to John Matthews this two solution add to me good background about what is the problem was Or get rid of the problem altogether so you don't have to 'remember' to do anything, and change the containing struct: struct maiN { struct sub s1; /* changed from pointer to the object itself */ int c; }; Making the code in the OP work as expected (changing the redirection of course): int main() { struct maiN s0; strcpy(s0.s1.name,hi man ); return 0; } 2nd : no the target of my code is to access a variable from it's parent and child class so I use pointer
[c-prog] Re: Nested structure segmentation fault ??
One other minor point: you can use typedef to save some typing: typedef struct sub { /* remove sub if you want */ : } Sub; typedef struct maiN { /* remove maiN if you want */ : } MaiN; int main(void) { Sub sub0; /* no need for struct */ MaiN s0; /* no need for struct */ John
Re: [c-prog] Re: integer promotions
John Matthews wrote: --- In c-prog@yahoogroups.com, Pedro Izecksohn [EMAIL PROTECTED] wrote: OK, I wrote a bad piece of code. Let me try to codify my problem again: #include limits.h #include stdio.h int main (void) { unsigned short int a; unsigned long long int b, c; a = USHRT_MAX; b = (a*a); c = ((unsigned int)a*(unsigned int)a); printf (Why %llx != %llx ?\n, b, c); return 0; } When I execute it I get: Why fffe0001 != fffe0001 ? b is wrong. I see what you are saying - ignoring what C says should happen, and assuming USHRT_MAX = 0x, you have: b = a * a = 0x * 0x = 0xfffe0001 So why do you get 0xfffe0001? Good question - my guess is that at some point the result is a negative (ie. signed) value, and this gets sign-extended. For example, if you have -1 as a signed short, and want to convert it to a signed int, the result should still be -1. But if you like at these values in hex, you have 0x (short) becoming 0x (int), which looks similar to what has happened to b in your program. But hopefully some can quote the relevant bit of the Standard. John Wow. I totally missed that. All this time I was thinking the OP was complaining about something involving 'c' instead of 'b'. Without typecasting, _operators_ tend to behave oddly when differing data types are involved. At least they don't behave like you would think they should. There are a set of rules regarding these things in the Standard, but I've just found it MUCH easier to use typecasting to the types I want and then force a final typecast at the end of the procedure instead of trying to memorize the rules. b = (unsigned long long int)(((unsigned int)a) * ((unsigned int)a)); Ugly, but effective. Although, I would personally do something more along the lines of: b = (UInt64)(((UInt32)a) * ((UInt32)a)); (I'm pretty sure the rule is something like operators automatically convert from unsigned to signed unless there is a typecast involved on one of the operands, but don't quote me on that as I haven't ever tried to figure this out. My solution is to ALWAYS go overkill on typecasting in this situation to make 100% certain that the compiler will do EXACTLY what I want it to do. My approach has never failed me but it does use a lot of parenthesis.) -- Thomas Hruska CubicleSoft President Ph: 517-803-4197 *NEW* MyTaskFocus 1.1 Get on task. Stay on task. http://www.CubicleSoft.com/MyTaskFocus/
[c-prog] Re: integer promotions
--- In c-prog@yahoogroups.com, Thomas Hruska [EMAIL PROTECTED] wrote: BTW, you should have your compiler warnings turned up so that you get a warning for assigning a signed value to an unsigned variable. Thomas- is this easy in Microsoft world? And anyone know the gcc equivalent? Gcc's -Wall 'all warnings' option doesn't include it. I know that when I've PC/Flexe-lint (embedded) code that hasn't been PC/Flexe-linted before, the signed/unsigned warnings are usually some of the first to be disabled because there are so many of them, and because they are less likely to be 'real' bugs (I'm not saying it's ok to ignore them, just that they're towards the end of the 'to do' list). John
Re: [c-prog] Re: integer promotions
On Sun, Nov 23, 2008 at 2:57 PM, John Matthews [EMAIL PROTECTED] wrote: --- In c-prog@yahoogroups.com, Thomas Hruska [EMAIL PROTECTED] wrote: BTW, you should have your compiler warnings turned up so that you get a warning for assigning a signed value to an unsigned variable. Thomas- is this easy in Microsoft world? And anyone know the gcc equivalent? Gcc's -Wall 'all warnings' option doesn't include it. If you include 'unsigned' in the cast, then there won't be a warning, since you're not longer assigning a signed value to an unsigned one. -- PJH http://shabbleland.myminicity.com/tra
[c-prog] Re: integer promotions
--- In c-prog@yahoogroups.com, Paul Herring [EMAIL PROTECTED] wrote: On Sun, Nov 23, 2008 at 2:57 PM, John Matthews [EMAIL PROTECTED] wrote: --- In c-prog@yahoogroups.com, Thomas Hruska thruska@ wrote: BTW, you should have your compiler warnings turned up so that you get a warning for assigning a signed value to an unsigned variable. Thomas- is this easy in Microsoft world? And anyone know the gcc equivalent? Gcc's -Wall 'all warnings' option doesn't include it. If you include 'unsigned' in the cast, then there won't be a warning, since you're not longer assigning a signed value to an unsigned one. I meant in code without casts. (Apologies if this post is a repeat- first attempt appeared to fail.)
[c-prog] Re: integer promotions
--- In c-prog@yahoogroups.com, Thomas Hruska [EMAIL PROTECTED] wrote: b = (UInt64)(((UInt32)a) * ((UInt32)a)); Would this be even safer: b = (UInt64)a * (UInt64)a; ?
Re: [c-prog] Re: integer promotions
On Sun 2008-11-23 14:57:38 UTC-, John Matthews ([EMAIL PROTECTED]) wrote: BTW, you should have your compiler warnings turned up so that you get a warning for assigning a signed value to an unsigned variable. Thomas- is this easy in Microsoft world? And anyone know the gcc equivalent? I'm not Thomas, but I think it's: cl -W4 Gcc's -Wall 'all warnings' option doesn't include it. Maybe try: gcc -W -Wall
Res: [c-prog] Re: integer promotions
--- Thomas Hruska wrote: BTW, you should have your compiler warnings turned up so that you get a warning for assigning a signed value to an unsigned variable. --- John Matthews asked: And anyone know the gcc equivalent? Gcc's -Wall 'all warnings' option doesn't include it. --- andrew clarke replied: Maybe try: gcc -W -Wall The right answer is: gcc -Wconversion
Re: [c-prog] Re: integer promotions
John Matthews wrote: --- In c-prog@yahoogroups.com, Thomas Hruska [EMAIL PROTECTED] wrote: b = (UInt64)(((UInt32)a) * ((UInt32)a)); Would this be even safer: b = (UInt64)a * (UInt64)a; ? That would do something different. It really depends on what exactly you want to do. I'd still probably end up wrapping the whole thing up in one final typecast just-because-I-can. The compiler will probably end up ignoring the final typecast as a no-op. -- Thomas Hruska CubicleSoft President Ph: 517-803-4197 *NEW* MyTaskFocus 1.1 Get on task. Stay on task. http://www.CubicleSoft.com/MyTaskFocus/
[c-prog] String and Numbers
Hi I have text file in this pattern Jila Tim 45 45 67 5 67 45 3 5 67 89 19823456 Eva Clarare 42 1 8 43 52 76 1 8 90 43 19345678 - - - - - Kim Jomte 4 5 75 24 52 52 35 35 36 35 19745432 I want to get name of each player and total higest score palyer. the last eight digits are not required. Please guide me how to write code. Regards Jan [Non-text portions of this message have been removed]
[c-prog] util class for general method
Hi, Im curious is it usual to make an util class to contain methods that are going to be used frequently generally? is there any proper format for this class? im planning to make a util.cpp file with some methods, and include the cpp file in every classes. but i wonder since i havent seen an included .cpp files(all included are header files) thanks in advance
[c-prog] print number in string
Hello list, I'm used to c++ where I can just use a simple stringstream and print the number to the stream. Unfortunately for me, I'm using c now, and need to be able to print a number in a string. Basically, I'm writing a time conversion util; it takes the number of seconds and converts them to weeks,days,hours,minutes and seconds. So, I need to print the number of each denomination to a buffer. Thanks, Tyler Littlefield email: [EMAIL PROTECTED] web: tysdomain-com Visit for quality software and web design. skype: st8amnd2005
Re: [c-prog] print number in string
On Sun, Nov 23, 2008 at 7:51 PM, Tyler Littlefield [EMAIL PROTECTED] wrote: I'm used to c++ where I can just use a simple stringstream and print the number to the stream. Unfortunately for me, I'm using c now, and need to be able to print a number in a string. Basically, I'm writing a time conversion util; it takes the number of seconds and converts them to weeks,days,hours,minutes and seconds. So, I need to print the number of each denomination to a buffer. Read up on printf(), it's the canonical function call from stdio.h for printing formatted strings. -- Brett In the rhythm of music a secret is hidden; If I were to divulge it, it would overturn the world. -- Jelaleddin Rumi
Re: [c-prog] print number in string
thanks. looks like what I needed, though sprintf might serve a better purpose. Thanks, Tyler Littlefield email: [EMAIL PROTECTED] web: tysdomain-com Visit for quality software and web design. skype: st8amnd2005 - Original Message - From: Brett McCoy To: c-prog@yahoogroups.com Sent: Sunday, November 23, 2008 5:58 PM Subject: Re: [c-prog] print number in string On Sun, Nov 23, 2008 at 7:51 PM, Tyler Littlefield [EMAIL PROTECTED] wrote: I'm used to c++ where I can just use a simple stringstream and print the number to the stream. Unfortunately for me, I'm using c now, and need to be able to print a number in a string. Basically, I'm writing a time conversion util; it takes the number of seconds and converts them to weeks,days,hours,minutes and seconds. So, I need to print the number of each denomination to a buffer. Read up on printf(), it's the canonical function call from stdio.h for printing formatted strings. -- Brett -- In the rhythm of music a secret is hidden; If I were to divulge it, it would overturn the world. -- Jelaleddin Rumi [Non-text portions of this message have been removed]
Res: [c-prog] util class for general method
--- Jos Timanta Tarigan wrote: im planning to make a util.cpp file with some methods, and include the cpp file in every classes. but i wonder since i havent seen an included .cpp files(all included are header files) You should not include .cpp files in other .cpp files, but you should instead include a .h header, compile both files separately and link them together. How to do this? It depends on your compiler and platform. It also depends on: Do you want your general library to be a shared library? Or do you want it to be packed with every executable? (Static or dynamic linkage?)
Res: [c-prog] String and Numbers
--- Mirza Abdullah Jan wrote: Hi I have text file in this pattern Jila Tim 45 45 67 5 67 45 3 5 67 89 19823456 Eva Clarare 42 1 8 43 52 76 1 8 90 43 19345678 - - Kim Jomte 4 5 75 24 52 52 35 35 36 35 19745432 I want to get name of each player and total higest score palyer. the last eight digits are not required. Please guide me how to write code. As your teacher or look in your book about formatted input and the function fscanf.
[c-prog] Re: integer promotions
Tyler Littlefield [EMAIL PROTECTED] wrote: hello, If you multiply two unsigned shorts together, you'll get an unsigned short, No, you won't. If the range of unsigned short fits into an int, the two unsigned short values will be promoted to int. The multiplication will be performed with ints, resulting in either an int or undefined behaviour if the value is not in the range of int. If the range of unsigned short doesn't fit into an int, then the unsigned short values will be promoted to unsigned int. The multiplication will be performed as unsigned int and will result in an unsigned int. The result cannot overflow; it will be reduced modulo 1 more than UINT_MAX if the result value is outside the range of unsigned int. -- Peter
[c-prog] Re: integer promotions
Pedro Izecksohn [EMAIL PROTECTED] wrote: If The integer promotions preserve value including sign. There are several 'promotion' rules at play in C (and C++.) For integers with a 'rank' less than int, if the range of the integer type fits into the range of int, then that type will promote to int, if it is promoted. If the range won't fit into an int, it will be promoted to an unsigned int. More precisely, if USHRT_MAX = INT_MAX, then an unsigned short that is subject to integral promotion will promote to an int; otherwise, it will promote to an unsigned int. Aside: arithmetic promotion occurs when the promoted types don't match. For instance, if you multiplying an unsigned int by an int, then the int will be promoted to unsigned int. Consider the test: (-1 (unsigned short) 1) Whilst intuitively it should always be true, there are many implementations where it is false! #include stdio.h int main (void) { unsigned short int a; unsigned long long int b, c; a = -1; b = (a*a); Here's a table of what a will promote to, and the type of a * a, dependant on the maximum values of unsigned short, int and unsigned int: USHRT_MAXINT_MAX UINT_MAX a * a --- -- 0x 0x7FFF 0x unsigned int 0x 0x7FFF 0x int 0x 0x7FFF 0x unsigned int The respective values of a * a for the three cases will be: 1, overflow and 0xFFFE0001. In the overflow case, the behaviour is undefined, so the compiler can do whatever it wants. But, if we pretend that we have the usual vanilla twos- complement behaviour, the resulting int will be -131071. Now when that value is converted to an unsigned integer type, the value produced will be converted modulu one more than the maximum value for that unsigned type. If we suppose that unsigned long long has the range 0..0x, then the result value will be 0xFFFE0001 (in decimal 18446744073709420545.) Paul Herring [EMAIL PROTECTED] wrote: Here you're multiplying two shorts. There's no short in sight. c = ((unsigned int)a*(unsigned int)a); Here you're multiplying two ints. There's no int in sight either. I sounds like I'm overly nitpicking, but when it comes to promotion rules, you need to be _very_ specific about type, including signedness. Clearly, on your compiler, shorts are a different size to ints. Now I will be overly nitpicking. :-) The size (in the sizeof sense) is irrelevant. The _range_ of values is what is crutial. printf (Why %llx != %llx ?\n, b, c); [Why fffe0001 != fffe0001 ?] Assuming UINT_MAX is 0x, 0xu * 0xu is 0xFFFE0001. Storing that positive 32-bit value into a 64-bit unsigned type isn't going to change the value! Unsigned integers do not get sign-extended when promoted to wider unsigned integer types. Why? Because there is no sign to extend! return 0; } I believe you have the usual two problems. First, you believe promotion works from the outside in. In other words, the type of the variable you're assigning to will influence the types and promotion of the expression on the right hand side. They won't. It works from the inside out. Secondly, you've probably been confused by 'hex' output in combination with badly written books that encourage you to think of representations, rather than in terms of values. The C (and C++) languages convert numbers in terms of values and type, not representations. Unfortunately, some authors are so fascinated by the concept of representation, particularly twos-complement, that they forget that it's entirely _irrelevant_ when explaining how integers work in C! -- Peter
[c-prog] Re: integer promotions
For peternilsson42: I was not clear and you did not read message 68798. http://tech.groups.yahoo.com/group/c-prog/message/68798 To clarify: That code I compiled on two independent compilers. On both compilers: USHRT_MAX is 0x UINT_MAX is 0x ULLONG_MAX is 0x For integers with a 'rank' less than int, if the range of the integer type fits into the range of int, then that type will promote to int, if it is promoted. If the range won't fit into an int, it will be promoted to an unsigned int. It shows that you read the standard. Consider the test: (-1 (unsigned short) 1) Whilst intuitively it should always be true, there are many implementations where it is false! The unsigned short value 1 fits into an int and -1 is an int, so, according to the standard this test must be true. a = -1; I changed this line in message 68798 to: a = USHRT_MAX; Here's a table of what a will promote to, and the type of a * a, dependant on the maximum values of unsigned short, int and unsigned int: I'm sorry I was not sufficiently clear. Unsigned integers do not get sign-extended when promoted to wider unsigned integer types. Why? Because there is no sign to extend! This is exactly how I thought before I saw two independent compilers producing the binaries that result that result. First, you believe promotion works from the outside in. In other words, the type of the variable you're assigning to will influence the types and promotion of the expression on the right hand side. They won't. It works from the inside out. No. I used unsigned short int and unsigned long long int because the original calculation needs them, because the result of the original calculation may not fit inside an unsigned int. The original calculation is more complex than a multiplication of two integers. Secondly, you've probably been confused by 'hex' output No. I used hexadecimal representation because these extreme values are best represented in hexadecimal. I hope that you answer my question, that is explicit in my other message. My personal opinion is that the two independent compilers I used are buggy, but I want another opinion before reporting this bug to two independent developers.
[c-prog] Re: integer promotions
Pedro Izecksohn [EMAIL PROTECTED] wrote: For peternilsson42: I was not clear and you did not read message 68798. http://tech.groups.yahoo.com/group/c-prog/message/68798 That post contained detail missing from your original post. However, it did not contain detail which explained why you where confused. To clarify: That code I compiled on two independent compilers. On both compilers: USHRT_MAX is 0x UINT_MAX is 0x ULLONG_MAX is 0x For integers with a 'rank' less than int, if the range of the integer type fits into the range of int, then that type will promote to int, if it is promoted. If the range won't fit into an int, it will be promoted to an unsigned int. It shows that you read the standard. It also explains the results you received. Consider the test: (-1 (unsigned short) 1) Whilst intuitively it should always be true, there are many implementations where it is false! The unsigned short value 1 fits into an int and -1 is an int, so, according to the standard this test must be true. On your machine perhaps, but there are any number of machines where USHRT_MAX INT_MAX. [DSPs seem to be more common than desktop PC's, but when I started C, most high end systems did not bother with 16-bit types. Everything was either 8-bit, or at least 32-bit.] a = -1; I changed this line in message 68798 to: a = USHRT_MAX; So you made absolutely _no_ change to the semantics of that assignment! Here's a table of what a will promote to, and the type of a * a, dependant on the maximum values of unsigned short, int and unsigned int: I'm sorry I was not sufficiently clear. Your post didn't need to be. I was trying to explain the language, but using three examples as illustration. You seem to be only interested in one class of machine. No matter... ;-) Unsigned integers do not get sign-extended when promoted to wider unsigned integer types. Why? Because there is no sign to extend! This is exactly how I thought before I saw two independent compilers producing the binaries that result that result. I don't understand that sentence. No conforming implementation can exhibit sign extension for an unsigned integer type since no unsigned integer type has a sign bit. First, you believe promotion works from the outside in. In other words, the type of the variable you're assigning to will influence the types and promotion of the expression on the right hand side. They won't. It works from the inside out. No. I used unsigned short int and unsigned long long int because the original calculation needs them, because the result of the original calculation may not fit inside an unsigned int. That's fine, but it doesn't explain why you found the results confusing. Misunderstanding promotion explains it perfectly. :-) The original calculation is more complex than a multiplication of two integers. Well, if you're ready, you might like to post the more complicated example. Secondly, you've probably been confused by 'hex' output No. I used hexadecimal representation because these extreme values are best represented in hexadecimal. I didn't mean you couldn't read hex, I meant that many people see hex, they have a conditioned response to believe that the hex value _is_ the representation, as well as, the value. I hope that you answer my question, that is explicit in my other message. My previous message explains precisely why you received the output you received. But instead of explaining it in terms of one specific machine, I tried to explain the language itself, showing three possible implementations, one of which appears to match the machine you're using. My personal opinion is that the two independent compilers I used are buggy, I've actually demonstrated why they're not. but I want another opinion before reporting this bug to two independent developers. You would look very foolish if you reported this as a bug. But, for the sake of trying to make my post a little clearer, let's suppose we have an implementation that you describe above... USHRT_MAX is 0x UINT_MAX is 0x ULLONG_MAX is 0x This isn't enough to fully explain what's going on so let me add the reasonable assumption: INT_MAX is 0x7FFF Now, let's start... unsigned short int a; unsigned long long int b, c; All good. [BTW, many people tend not to bother with 'int' when using unsigned types.] a = USHRT_MAX; This will assign a the value 0x. So will a = -1 on your machine as (USHRT_MAX plus 1) plus (minus 1) is USHRT_MAX. b = (a*a); Forget about b = and the parentheses. The first detail is a * a. Now since a has lower rank than int, it is subject to integral promotion in that sub-expression. Since USHRT_MAX INT_MAX, it promotes to int. Thus, the statement (on this particular machine) is the same as: b = (65535 * 65535); Now 65535 * 65535 has the _mathematical_