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'

Programming languages, Coding, Executables, Package Creation, and Scripting.
Post Reply
Message
Author
Caitlin
Posts: 329
Joined: 2012-05-24 07:32
Has thanked: 3 times
Been thanked: 2 times

[CLOSED] 0xe3 Vs. '\xe3'

#1 Post by Caitlin »

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
Last edited by Caitlin on 2015-10-02 14:45, edited 1 time in total.

BowCatShot
Posts: 959
Joined: 2006-07-15 12:08

Re: 0xe3 Vs. '\xe3'

#2 Post by BowCatShot »

Interesting, 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 == '\xe3')
    printf("values match\n");

}
I get
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");

}
I get

values are e3 e3
values match

tomazzi
Posts: 730
Joined: 2013-08-02 21:33

Re: 0xe3 Vs. '\xe3'

#3 Post by tomazzi »

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.
Odi profanum vulgus

Caitlin
Posts: 329
Joined: 2012-05-24 07:32
Has thanked: 3 times
Been thanked: 2 times

Re: 0xe3 Vs. '\xe3'

#4 Post by Caitlin »

I thought it was something like that. Thanks.

Regards,

Caitlin

Post Reply