1
int main() {
    char ch = 'a';
    int x;
    x = ch; 
    printf("x=%c", x);
}

Is this code safe to use (considering endiness of machine)?

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 2
    considering that int is usually bigger than char, I would say yes. – njzk2 Sep 12 '14 at 14:54
  • 4
    Note that `char` *is* "an integer type". – unwind Sep 12 '14 at 14:57
  • my actual programm is doing something like: int getchoice(.........)//plz ignore arguments type int main() { ----------- ------------ printf("u hv chosen:%c",getchoice); ----------- } int getchoice(------) { int slected; ---------- --------- slected=getchar(); ------ ------ return slected; } – debendra nath tiwary Sep 12 '14 at 15:04
  • character literals are always of type int in C, so you the cast is redundant – phuclv Sep 12 '14 at 15:16
  • Do not edit your question after getting answers. – haccks Sep 12 '14 at 15:19

5 Answers5

3

Yes, it is safe to cast a character (like char) type to an integer type (like int).

In this answer and others, endian-ness is not a factor.

There are 4 conversions going on here and no casting:

  1. a is character of the C encoding. 'a' converts to an int at compile time.

    'a'
    
  2. The int is converted to a char.

    char ch = 'a';
    
  3. The char ch is converted to an int x. In theory there could be a loss of data going from char to int **, but given the overwhelming implementations, there is none. Typical examples: If char is signed in the range -128 to 127, this maps well into int. If char is unsigned in the range 0 to 255, this also maps well into int.

    int x;
    x = ch; 
    
  4. printf("%c", x) uses the int x value passed to it, converts it to unsigned char and then prints that character. (C11dr §7.21.6.1 8 @haccks) Note there is no conversion of x due to the usual conversion of variadic parameters as x is all ready an int.

    printf("x=%c", x);
    

** char and int could be the same size and char is unsigned with a positive range more than int. This is the one potential problem with casting char to int although typically there is not loss of data. This could be further complicated should char have range like 0 to 2³²-1 and int with a range of -(2³¹-1) to +(2³¹-1). I know of no such machine.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • There is no guarantee that `ch` is an `unsigned char`. – haccks Sep 12 '14 at 17:14
  • `INT_MAX < CHAR_MAX` is strange (on a hosted implementation). Could I print a `char` with `printf` and `%c` on this platform? `%c` expects an `int`... While there may be reasons to have `int` and `char` with the same size on some machine, I don't see a reason why `char` should be unsigned there. – mafso Sep 12 '14 at 17:14
  • @haccks: I think that's meant to read "...and `char` could be unsigned..." – mafso Sep 12 '14 at 17:15
  • @mafso; OK. Its time to delete my answer. – haccks Sep 12 '14 at 17:29
  • @mafso Thanks for the correction. The last paragraph should be -(power(2,31) -1) to power(2,31)-1 and not using 32 as earlier posted. This is intentionally one different than your suggestion of `-power(2,31)` given that odd-ball machine may use one's complement or sign-magnitude integers. – chux - Reinstate Monica Sep 12 '14 at 17:47
  • 1
    @mafso My concern about `INT_MAX < CHAR_MAX` stems from a post http://stackoverflow.com/a/25776962/2410359 Agree such a machine would be quite esoteric. – chux - Reinstate Monica Sep 12 '14 at 17:54
  • 1
    Thanks for the link; My thoughts that `sizeof(int) == sizeof(char)` implies `char` being signed (on a hosted implementation) came from here: http://stackoverflow.com/questions/3860943/can-sizeofint-ever-be-1-on-a-hosted-implementation, taking `printf("%c")` into account, additionally to `fputc`/`fgetc`. – mafso Sep 12 '14 at 18:10
  • FYI, on a 2's complement machine, the value with all bits 0 but the sign bit, may trap (that is, `INT_MIN` may be `-INT_MAX`). – mafso Sep 12 '14 at 18:13
  • @mafso Certainly thought `INT_MIN` had to be `-INT_MAX - 1` in 2's complement. Found this ref http://en.wikipedia.org/wiki/Two's_complement#Most_negative_number Do you have any ref that supports the "may trap" option for C? or is that a question for SO? – chux - Reinstate Monica Sep 12 '14 at 18:22
  • 1
    C11 6.2.6.2 p2 "Which of these [sign and magnitude, two's complement, ones' complement] applies is implementation-defined, as is whether the value with sign bit 1 and all value bits zero (for the first two), [...], is a trap representation or a normal value." Don't know if that exists, though. – mafso Sep 12 '14 at 18:29
1

Yes, casting integer types to bigger integer types is always safe.

Standard library's *getc (fgetc, getchar, ...) functions do just that--they read unsigned chars internally and cast them to int because int provides additional room for encoding EOF (end of file, usually EOF==-1).

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
0

Yes it is, because int is bigger than char, but using char instead of int would not be safe for the same reason.

mantal
  • 1,093
  • 1
  • 20
  • 38
  • 1
    Note: C does not specify `int` is bigger than `char`. `CHAR_MAX` may greater than `INT_MAX`. Consider if `int` and `char` the same size and `char` is unsigned. – chux - Reinstate Monica Sep 12 '14 at 15:40
0

it is safe here because char is converted to int anyway when calling printf.

see C++ variadic arguments

programmerjake
  • 1,794
  • 11
  • 15
0

What you are doing is first =

int x = ch => Assigning the ascii value of the char to an int

And finally : printf("x=%c", x); => Printing the ascii value as a char, which will print the actual char that correspond to that value. So yeah it's safe to do that, it's a totally predicatable behaviour.
But safe does not mean useful as integer is bigger than char, usually we do the inverse to save some memory.

Nicolas Charvoz
  • 1,509
  • 15
  • 41
  • It's highly doubtful that ASCII is the character set and encoding; more likely Windows-1252 or similar, IBM437, or UTF-8. – Tom Blodget Sep 13 '14 at 00:40