... or a misunderstanding on my part ?
From string "\x0CTUV", the compiler generates 0x0C 0x55 0x56 0x57 0x00
From string "\x0CABC", the compiler generates 0xCA 0x42 0x43 0x00 ... rather than the expected 0x0C 0x41 0x42 0x43 0x00
I thought the \x escape sequence in a string instructed the compiler to encode the very next two characters as a hexadecimal byte.
Am I missing something ?
Don't assume that it will encode the next two characters. If the next character after your constant is a valid hexadecimal character, I recommend that you do: "\x0C""ABC" to make sure that you have separated your hexadecimal character from any following characters.
> Don't assume that it will encode the next two characters.
Well, apparently I shouldn't, but do you think it was an unreasonble assumption? I don't. I've never read that this escape sequence ignores a leading zero when the 3rd character is a valid hex digit. It makes no sense.
but do you think it was an unreasonble assumption?
Yes, it was unreasonable, because it contradicts what the language definition says about \x. There are specific examples in the C99 standard demonstrating exactly this pitfall (6.4.4.4 paragraph 14, 6.4.5 paragraph 7).
The deeper reason for this is that C doesn't assume chars are always 8 bits wide.
You just assumed that it accepts two non-zero charactersc :)
It will continue to eat characters until the first non-valid character is found.
gcc would consume every signle character in your second string, and then complain about "hex escape sequence out of range".
"There are specific examples in the C99 standard"
I don't have the C99 standard, but C90 specifically states:
"Each octal or hexadecimal escape sequence is the longest sequence of characters that can constitute the escape sequence" (my emphasis).
So C51 is behaving exactly as specified!
OK, but ... 1) In Kiel C51, what exactly is the \x escape sequence supposed encode? A single character? Multiple characters? 2) In the case of \x, is "the longest sequence of characters that can constitute the escape sequence" all hexadecimal characters ?
\x will consume all combinations of 0..9, a..f, A..F for any length of characters up to any possible compiler-specific limitation of a string. If the compiler can handle 2000 character long strings, then it can consume a very, very long number of hexadecimal characters.
However, most compilers will issue a warning if the hexadecimal constant overflows the max range for a character. I haven't looked into the standard if it is allowed, but there are compilers who will treat too long hex constants as an error. Note that a character does not have to be 8 bits large. Wide characters are normally 16 bit, but some architectures can have completely different character sizes.
I leave it to C51 users to discuss specific limits for the Keil compiler. The important thing for you is to make sure that the compiler can not consume more characters than you specifically want to belong to the hex constant. My first post shows what I normally do.
The important thing for you is to make sure that the compiler can not consume more characters than you specifically want to belong to the hex constant. My first post shows what I normally do.
I agree. What's odd, however, is why the compiler seemingly ignores leading zeros, rather than consuming all valid hex characters following the \x. Refering back to my original post, you'll see that the "\x0CABC" does NOT consume the B and the C in the string ... both of which by definition are valid hexidecimal digits. It apparently ignores the leading zero, then encodes the next TWO digits ( the C and A in this case ).
Now, given that this forum's primary purpose is a venue for debate rather than assistance, I will accept the obligatory ongoing debate, but you do have to admit that the behavior of the \x conversion is a bit odd. No ?
View all questions in Keil forum