In a program of mine, I have the following statements:
unsigned char currline[MAXWIDTH + 4];
if (g.currline[thiscol] == 0xe3)
and it works as I expect it to. But if I change the second statement to:
if (g.currline[thiscol] == '\xe3')
it NEVER compares equal. Is this something to do with extending the sign bit?
This isn't really a request for advice; this is more of a request for understanding.
Caitlin
Scheduled Maintenance: We are aware of an issue with Google, AOL, and Yahoo services as email providers which are blocking new registrations. We are trying to fix the issue and we have several internal and external support tickets in process to resolve the issue. Please see: viewtopic.php?t=158230
[CLOSED] 0xe3 Vs. '\xe3'
-
- Posts: 959
- Joined: 2006-07-15 12:08
Re: 0xe3 Vs. '\xe3'
Interesting, when I run:
I get
values are e3 e3
but when I run:
I get
values are e3 e3
values match
Code: Select all
#include <stdio.h>
int main() {
unsigned char x1 = 0xe3;
unsigned char x2 = '\xe3';
printf("values are %x %x\n",x1,x2);
if(x1 == '\xe3')
printf("values match\n");
}
values are e3 e3
but when I run:
Code: Select all
#include <stdio.h>
int main() {
unsigned char x1 = 0xe3;
unsigned char x2 = '\xe3';
printf("values are %x %x\n",x1,x2);
if(x1 == (unsigned char)'\xe3')
printf("values match\n");
}
values are e3 e3
values match
Re: 0xe3 Vs. '\xe3'
Immediate constant '\xe3' without literal type specifier is by default treated as signed, so it's automatically expanded to register-size variable: 0xFFFFFFE3. Therefore it doesn't match 0xe3, because hex notation always produces unsigned constants -> 0x000000E3.
On the other hand, for x2 it doesn't matter what type of constant is assigned, because for a single byte arithmetic expansion doesn't change anything, i.e. (signed) -1 == (unsigned) 0xFF.
edit:
To avoid such nasty surprises, immediate constants should always be type-casted. Global or frequently used constants can be either defined as a global constants of some type (not very efficient) or defined as a preprocessor symbol, like this:
#define CONSTANT_16 ((uint16_t) <value> )
Besides this, literal type specifiers are in fact also very dangerous and non portable, f.e.:
On Linux with gcc:
(int64_t) -1 == -1L
On windows with mingw:
(int64_t) -1 == -1LL
This is an effect of using ancient, non-standardized and therefore non-portable types like int, long long int or short.
Portable types, which are guaranteed to work everywhere are those with explicitly exposed size, like uint16_t, int64_t, int128_t ... etc.
F.e. on AVR sizeof(int) == sizeof(char) - this is an 8-bit architecture. All algorithms tested on x86, which are using "int" types will most likely fail on AVR. But, You can use int16_t to write algorithms which will work properly on both AVR and x86_64. The compiler will generate correct, equivalent code in both cases
/edit
Regards.
On the other hand, for x2 it doesn't matter what type of constant is assigned, because for a single byte arithmetic expansion doesn't change anything, i.e. (signed) -1 == (unsigned) 0xFF.
edit:
To avoid such nasty surprises, immediate constants should always be type-casted. Global or frequently used constants can be either defined as a global constants of some type (not very efficient) or defined as a preprocessor symbol, like this:
#define CONSTANT_16 ((uint16_t) <value> )
Besides this, literal type specifiers are in fact also very dangerous and non portable, f.e.:
On Linux with gcc:
(int64_t) -1 == -1L
On windows with mingw:
(int64_t) -1 == -1LL
This is an effect of using ancient, non-standardized and therefore non-portable types like int, long long int or short.
Portable types, which are guaranteed to work everywhere are those with explicitly exposed size, like uint16_t, int64_t, int128_t ... etc.
F.e. on AVR sizeof(int) == sizeof(char) - this is an 8-bit architecture. All algorithms tested on x86, which are using "int" types will most likely fail on AVR. But, You can use int16_t to write algorithms which will work properly on both AVR and x86_64. The compiler will generate correct, equivalent code in both cases
/edit
Regards.
Odi profanum vulgus