Thread: Hex Chars to Binary (XOR Swap split)

  1. #16
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Oh please tell me fischerandom doesn't code professionally for a living.

    Code:
    #include <stdio.h>
    int main ( ) {
      int a = 22, b = 44;
      printf( "%d %d\n", a, b );
      a ^= b ^= a ^= b;
      printf( "%d %d\n", a, b );
      return 0;
    }
    
    gcc -W -Wall -g foo.c
    foo.c: In function ‘main’:
    foo.c:5: warning: operation on ‘a’ may be undefined
    If your compiler can't tell you you've messed up, either get a better compiler or learn what undefined, unspecified and implementation defined behaviours are.

    > Put ut some fresh link!
    Why? Do you assume that something is wrong simply because it's old?
    The CLC FAQ has the widest possible review of way more people that know way more about C than any single person could hope to achieve.

  2. #17
    Registered User fischerandom's Avatar
    Join Date
    Aug 2005
    Location
    Stockholm
    Posts
    71
    Throwing a monkey wrench at Prelude & c/o's attempts so far. I know that you think that you understand what you thought that I said but I am not so sure that you understand that what you read was not what I ment. How is it possible to write a C compiler that interprets this line a ^= b ^= a ^= b to yield anything else than the final result of a ^= b; b ^= a; a ^= b;, etc? I know they must have decided when creating the C standard that it was just too much work to list all possible cases with all operators, so they just said that it is undefined behaviour for all cases. But if you think about this case I am sure it can be excluded.

    So far, only a single link to an old (1995) source to the C Standard have been found by you guys, I am sure there must be more than a bunch of fresher (and also free) links on the net that you can show here to prove your point. No more copy and paste text from your sources/books it makes no sense at all to do that, for bovious reasons.
    Bobby Fischer Live Radio Interviews http://home.att.ne.jp/moon/fischer/

  3. #18
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I did quote C99. Just because YOU don't have it, doesn't mean the reast of us are lacking.


    Quzah.
    Hope is the first step on the road to disappointment.

  4. #19
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >How is it possible to write a C compiler that interprets this line a
    >^= b ^= a ^= b to yield anything else than the final result of a ^= b; b ^= a; a ^= b;, etc?
    Compilers are allowed to optimize expressions in a number of ways, including reordering the operations. If you don't include a sequence point, it's possible that your compiler could order the operations in such a way that the result would be something other than you expect. So not only is it possible to write a compiler that gives the wrong result for your undefined expression, it's very likely if you use an aggressively optimizing compiler.

    >I am sure there must be more than a bunch of fresher (and also
    >free) links on the net that you can show here to prove your point.
    Why should we bother? You're doing the equivalent of plugging your ears and humming really loud by asking for proof and then denying it with some irrational argument when we provide it.
    My best code is written with the delete key.

  5. #20
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Quote Originally Posted by fischerandom
    So far, only a single link to an old (1995) source to the C Standard have been found by you guys, I am sure there must be more than a bunch of fresher (and also free) links on the net that you can show here to prove your point. No more copy and paste text from your sources/books it makes no sense at all to do that, for bovious reasons.
    I'm sorry if you are too cheap to buy a copy of the standard. I mean $18 wow thats just so much. There are enough people here with copies of the standard that if someone made a quote they'd be jumped on and corrected. Much like you are right now.

    Since this topic has gotten so derailed I'm gonna split it so the poor OP can have his thread back and maybe get an answer that helps them.

  6. #21
    Registered User TactX's Avatar
    Join Date
    Oct 2005
    Location
    Germany.Stuttgart
    Posts
    65
    Quote Originally Posted by ANSI ISO IEC 9899-1999 aka "C99" - 6.5 Page 67
    Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
    It also gives an emample on this:
    Quote Originally Posted by ANSI ISO IEC 9899-1999 aka "C99" - 6.5 Page 67
    This paragraph renders undefined statement expressions such as

    i = ++i + 1;
    a[i++] = i;

    while allowing

    i = i + 1;
    a[i] = i;
    Edit: removed redundancy

  7. #22
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Just for cheapskates who can't be bothered to fork out $18
    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n869/
    It's the last public draft of C99, but you can be pretty sure it says the same as the standard, especially when it comes to something fundamental as the nature of sequence points.

  8. #23
    Registered User fischerandom's Avatar
    Join Date
    Aug 2005
    Location
    Stockholm
    Posts
    71
    It says that I started this thread but I didn't! Who put my name there making it appear as if I have started this thread?
    Bobby Fischer Live Radio Interviews http://home.att.ne.jp/moon/fischer/

  9. #24
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Reading isn't your strong suit is it?

    Since this topic has gotten so derailed I'm gonna split it so the poor OP can have his thread back and maybe get an answer that helps them.
    Hex Chars to Binary (XOR Swap split)

  10. #25
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Another point to be made here is you will have a lot more to worry about when programming an application than a simple variable swap. This whole discussion stems from the fact that you think you have some god-like profound knowledge of doing a fast variable swap. If you really want a fast variable swap then use the assembly language opcode XCHG. But, seriously that is stupid. There are much bigger issues to discuss like this in programming that really do have some merit rather than this ridiculous swapping crap.

    I highly doubt using a temporary variable is gonna make or break your program. Just face it. You are wrong.

    I bet tons of companies would love to hire you because you figured out how to do a variable swap using a totally undefined and unsupported line of code. I can hear your phone now. Hear it? Didn't think so.

  11. #26
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by fischerandom

    So far, only a single link to an old (1995) source to the C Standard have been found by you guys, I am sure there must be more than a bunch of fresher (and also free) links on the net that you can show here to prove your point. No more copy and paste text from your sources/books it makes no sense at all to do that, for bovious reasons.
    The comp.lang.c FAQ is not the C standard (If you had read Quzah's posts thoroughly, you would have realised that he first pointed you to the CLC FAQ - the document which was copyright 1995 - and then posted from ANSI C99 in his next post. In other words, Quzah did not call the CLC FAQ the standard, therefore you are mistaken.) - however, as Salem correctly pointed out, (should you doubt Quzah's judgement for pointing you to the FAQ) the comp.lang.c FAQ 'has the widest possible review of way more people that know way more about C than any single person could hope to achieve.' Now the HTML version is somewhat behind the current version of the FAQ, (The FAQ itself tells you where you can get a current text version) but on this issue, there is little change, but I would say the new version goes even further to specify that swapping two values without a temporary variable is not particularly good practice, or useful.


    Question 20.15c How can I swap two values without using a temporary?

    A: The standard hoary old assembly language programmer's trick is:

    a^=b;
    b^=a;
    a^=b;

    But this sort of code has little place in modern, HLL programming. Temporary variables are essentially free, and the idiomatic code using three assignments, namely

    int t=a;
    a=b;
    b=t;

    is not only clearer to the human reader, it is more likely to be recognized by the compiler and turned into the most-efficient code (e.g. perhaps even using EXCH instruction). The latter code is obviously also amenable to use with pointers and floating-point values unlike the XOR trick. See also questions 3.3b and 10.3
    And since I believe you have not seen the current version of 3.3b in the FAQ:

    3.3b Here's a slick expression:

    a ^=b^=a^=b

    It swaps a and b without using a temporary.

    A: Not portably, it doesn't. It attempts to modify the variable twice between sequence points, so its behaviour is undefined.

    For example, it has been reported that when given the code

    int a = 123, b = 7654;
    a^=b^=a^=b;

    the SCO Optimizing C compiler (icc) sets b to 123 and a to 0.

    See also questions 3.1, 3.8, 10.3, and 20.15c.
    You see? It is what all of these good programmers have been telling you already.


    Now if you want to see this for yourself, that is, if you don't trust what I have given here, slide over to comp.lang.c and do a search for the FAQ or whatever.

    ~/
    Last edited by kermit; 11-25-2005 at 03:56 PM.

  12. #27
    Registered User fischerandom's Avatar
    Join Date
    Aug 2005
    Location
    Stockholm
    Posts
    71
    Thank you for your kind reply kermit. I like the tone in your letter! This "SCO Optimizing C compiler (icc)", what is that? Never heard of it. Is it something that professionals use or what? Amazing it fails I didn't think it was even possible. Now here is the thing, Metrowerks CodeWarrior is a very respected compiler and it did not even issue a warning about it, while the GCC (or MinGW that I tested with) issued a warning. I was thinking last night before sleeping if I should open up the GCC source code and find the code that would deal with this line "a ^= b ^= a ^= b;" and see exactly how it composes the assembly and exacly why it issues a warning. Then I also thought I should email Metrowerks and ask them why their compiler doesn't give me a warning about it? But then again it would be me who would be wrong anyway so I decide it is better to spend the time for my projects instead. But I am very amazed that the compiler did not first break it down to the normal 3 lines and then compose the assembler code. How is that possible to get wrong I thouht. And I think if we start at the GCC level it does it right, the way at least I think it should be, while an even more professional compiler such as CodeWarrior just does it right and does not bother with a warning, while less respectable compilers may fail to do it right, the way it should be.

    I see in the last posts there was also some grande missunderstandings:
    1. If anybody think that I think this XOR "trick" was something only I knew, no, I said it was an old classic trick.
    2. If anybody think that I think it swaps a and b faster with this XOR trick than using a temporary variable, no I never thought so, since he asked about XOR I thought maby it could be an interesting lesson (that I once thought was interesting). However, I pointed out that hardware based XOR memory swappers actually uses it and in that case it is faster, that is why they use it.
    3. If anybody think that I do not know assembly language (for a myraid of processors), I can tell you that I started with that and only years later learned to program the C language. Of course, if there is an exchange instruction it may be the fastest way to exchange two registers, but now we are in deeper water and we are talking C here, aren't we? I taught myself the binary number system and to program machine code from a book on the C64 and C128, that was the year 1983. Nobody helped me. Actually I learned to program in the GWBASIC language in 1982 on a Commodore PC-II, and I could spell the BASIC instructions before we even learned how to spell in school. One of my first programs in 1982 was making a program print '1', 'X', or '2' thirteen times in a row. I don't know if you have this in your contries (its guessing the results of socker game matches, etc.) I wanted to mention this because it sounded on Thantos as if I have no knowledge of assembler. But it was not untill 1990 when I could afford a Macintosh and start learning the C language and not untill 1994 before I started with C++, so I was quite late on that. I was born in 1975.
    Last edited by fischerandom; 11-26-2005 at 05:21 AM.
    Bobby Fischer Live Radio Interviews http://home.att.ne.jp/moon/fischer/

  13. #28
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You seem to be hung up on the difference between syntax and semantics.

    "Colourless green ideas sleep furiously".
    Perfect syntax, but utterly meaningless.

    Nobody is arguing that a ^= b ^= a ^= b; is invalid syntax. For sure any half decent compiler will have no trouble parsing it, and outputting some sequence of instructions which do "something".

    But that isn't the problem, it's a semantic issue - the code doesn't mean anything - it's undefined.
    Now your limited experience - as judged by your comment in ignorance "This "SCO Optimizing C compiler (icc)", what is that?" merely goes to show that your small world view of what compiler's are allowed to do simply isn't big enough.

    > such as CodeWarrior just does it right and does not bother with a warning,
    You can't possibly tell the difference between "doing it right" and "accidentally producing the answer I expect". Do you even know what the warning is telling you? I bet your code is a bad of fun when you change compilers or compile debug and release modes, if that's your attitude.

    Being a little bit undefined is the same as a little bit pregnant or a little bit dead - there is no such thing. It's an all or nothing deal. The fact that you've posted some really simple strawman expression which seems to prove your point doesn't wash - you have to consider all such expressions in whatever form they take (see later). You can't just pick "this one works" and "these don't".

    You're also hung up on the difference between "what my compiler does" and "what the language guarantees". You can dig into the code for your compiler and prothelise all you want about the real world choices it makes, but it won't affect what any other compiler chooses to do.
    Remeber -
    Defined behaviour - every compiler will produce code which has the same effect.
    Undefined behavior - you're on your own mate - good luck with that.

    > Now here is the thing, Metrowerks CodeWarrior is a very respected compiler and it did not even issue a warning about it
    There is no standard set of error messages, which is why for example gcc has many -W options, and why tools such as lint exist. If every compiler complained about every possible thing which could be determined from looking at the code, then very few people would make it past "hello world".

    Here bright boy, analyse this minor variation on your theme.
    Code:
    #include <stdio.h>
    
    int *f1 ( int *a ) { return a; }
    #define f2(a)  a
    
    int main ( ) {
      int a, b;
    
      a = 1; b = 2;
      *f1(&a) ^= *f1(&b) ^= *f1(&a) ^= *f1(&b);
      printf( "%d %d\n", a, b );
    
      a = 1; b = 2;
      f2(a) ^= f2(b) ^= f2(a) ^= f2(b);
      printf( "%d %d\n", a, b );
    
      return 0;
    }
    Here's my output
    Code:
    $ gcc foo.c && ./a.out
    0 1
    2 1
    Waaa!!!! where did my value go??
    Welcome to the world of undefined behaviour.

    And don't you dare back peddle into the "it only works in the simple case", because that's just admission that you really don't know what the ........ you're talking about.

  14. #29
    Registered User fischerandom's Avatar
    Join Date
    Aug 2005
    Location
    Stockholm
    Posts
    71
    Well, Salem, it must be like playing the Theremin programming on your system!
    This example has nothing to do with the example I originally posted, even though it may appear so. Both MinGW and CodeWarrior outputs:
    2 1
    2 1
    which is correct. Isn't MinGW based on GCC's sources? How could the output be so bad on your system?
    Bobby Fischer Live Radio Interviews http://home.att.ne.jp/moon/fischer/

  15. #30
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    You know I don't think Mister C was even as much trouble as this guy.

    Thread closed, you are more then welcome to return we you actually understand the difference between implementation and the standard, but until then don't let the door hit you on the way out.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 03-24-2006, 11:26 AM
  2. Hex Chars to Binary
    By drdepoy in forum C Programming
    Replies: 2
    Last Post: 11-24-2005, 12:44 PM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. Is binary HEX?
    By Budgiekarl in forum Tech Board
    Replies: 11
    Last Post: 11-23-2003, 09:02 AM