John Doe
John Doe

Reputation: 19

Storing a string in a integer variable in C

#include <stdio.h>
int main()
{
    int a = "Hi";
    char b = 'F';

    int c = a + b;

    printf("%d",a);        /* (1) */
    printf("%d",c);        /* (2) */ 
}

How come the output of the instruction (1) is 18537? How is it storing the value in terms of ANSI standard

Instruction (2) is clear since we are basically adding 70 to 18537 which gives 18607

Can some one elaborate on how the value is being stored in the integer variable in terms of string ?

Upvotes: 1

Views: 1724

Answers (3)

DDS
DDS

Reputation: 2479

What happend is basilally this:

int a = "Hi" // you allocate 4 bytes and put in the chars ('H' [0x48], 'i'[0x69], '\0' [0x0], 1_byte_of_rubbish) so is OK
//a = 0x 00 00 48 69

Note that first bit is interpreted as the 'signum' on int. Also remember that the value in memory should be 0X[rubbish]004869

char b= 'F' //you allocate 1 byte and give value F [0x46] (unsigned)
// b=0x46
printf("%d",a) // print what is inside variable a (as SIGNED integer)
 int c = a + b // you add a (signed) and b (unsigned) and put result in c (signed) -> 0x[00]004869 + 46 = 0x000048AF 
//c=0x000048AF

printf("%d",c) // you print the content of c interpreted as signed int

Note that most compilers initiate to 0 the variables so you get 00 [004869], if compiler would'nt do so, you gat something unpredictable as result because first byte of int is not initialized

Remember also endianess -> int on intel (little endian) machine are read with LSB first so print %d will give you wrong values ( in your case [48][69][00][00] = 26952 read as little endian)

EDIT: My suggestion is to always debug these cases "hexadecimally" so you can see exactly what is in each byte, decimel numbers sometimes (wehen it's about sorting) tells less.

Upvotes: 1

klutt
klutt

Reputation: 31306

Compiler warnings for the win!

$ cc -Wall -Wextra e.c 
e.c: In function ‘main’:
e.c:4:13: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
     int a = "Hi";
             ^~~~

You assign the memory address of the string literal to the variable a. Well, in many cases you do. However, this is not guaranteed and there are potential problems involved with this. For example, an int may not be enough to hold the whole address.

It could be worth pointing out that this is not valid C code, so do not do this. According to https://port70.net/~nsz/c/c11/n1570.html#6.5.16.1p1 (Thank you @Lundin for providing the link):

One of the following shall hold:112)

  • the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
  • the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
  • the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
  • the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.

See Lundin's answer for how to force the compiler to not accept invalid code.

Upvotes: 6

Lundin
Lundin

Reputation: 213678

int a = "Hi"; is not valid C code and speculating about what it might do on a non-standard compiler isn't very meaningful.

The code is a constraint violation of the rules of simple assignment 6.5.16.1. You cannot assign a char* to an int implicitly, without a cast.

(If you want to block invalid C code from compiling on the gcc compiler, use -std=c11 -pedantic-errors.)

Upvotes: 5

Related Questions