Link to home
Start Free TrialLog in
Avatar of Avik Dasgupta
Avik DasguptaFlag for United States of America

asked on

Confusing output

Hi ,
   I am stuck at a simple piece of C code as I cannot explain its output. Here it goes...

#include<stdio.h>
void main()
{
 int i="Hello",j;
 char * a;
 a="World";
 j=a;
 printf("i=%d  j=%d",i,j);
}

Output in both the cases is 170.
I am looking forward to a detailed explanation/discussion on this.

Thanks in advance,
Avik.
Avatar of Avik Dasgupta
Avik Dasgupta
Flag of United States of America image

ASKER

Sorry,
 output was i=170 j=176
Avatar of booki
booki

Avik77,

>> int i="Hello",j;

i gets address of const string "Hello"

>> a="World";

a gets address of const string "World"

>> j=a;

j gets address of const string "World"

>> printf("i=%d  j=%d",i,j);

output:

i=4342276 j=4341932

i'm not getting the same results as you...

b.

Avik77,

String literals in expressions are converted to pointers const strings.

For a detailed discussion see:
https://www.experts-exchange.com/questions/20917922/Strings-aren't-immutable.html

b.
Hi booki,

"Hello" and "World" should be string in consecutive locations in the literals block.  strlen("Hello") is 6.  The values that the poster is displaying are 70 and 76 - a difference of 6 cells.  (It would appear that your strings are located in different blocks.  Interesting....)


The poster may be using 16-bit integers and therefore getting only the lower 16 bits of the address.  


Kent
Avik77,

>> output was i=170 j=176

The difference of 6 is because "Hello\0" is 6 char long and is followed immediately in memory by "World\0".. However 170 and 176 seem to be quite low for valid pointer values...

I tried it on my linux box and still got similar results as my first post. ie:

i = 134513680  j = 134513686

// *note i-j == 6

What compiler/platform are you using?

b.
Kdo,

>> (It would appear that your strings are located in different blocks.  Interesting....)

Yup, the first run was with VC++7 on xp.. go figure.

b.
I tried this on VC++.Net 2002, and got a compile error:

error C2440: 'initializing' : cannot convert from 'const char [6]' to 'int'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast

That's compiling from the command line with the default warning level.

Oh well, if I cast I get:

i=4227552  j=4227560

I don't believe there is any requirement that to two static strings be consecutive in memory. In this case it looks like the linker is putting the strings on an 8 byte boundary.

I am trying in Turbo C++ v3.0. I agree to that of Booki because I have modified the program like this

#include<stdio.h>
void main()
{
 int i="Hello",j,k;
 char * a,*b;
 clrscr();
 a="";
 b="Thanks";
 j=a;k=b;
 printf("i=%d  j=%d  k=%d",i,j,k);
 getch();
}
and output is i=170  j=176  k=177
But still I am not getting why every first string gets always initialised to an integer with a value of 170 and then others follow as sequentially and also why different platforms are behaving so differently to this.

Avik.
It's because Turbo C++ v3.0 generates 16 bit code. The addresses 170 176 and so on relative to the segment where resides data.
Ok, but is the offset 170 a mandatory for initializing a string literal. If yes, then what *type* of data segment is this, can't we modify the value there. According to Booki it is a read only memory then why should any string literal be every time get initialized to an offset of 170 relative to the data segment. What may be stored from offset 0 to 169. Moreover why should a offset value  be printed rather than an address value. I have changed the int to unsigned int and the '%d' to '%u' but still the same.
Avik77,

>> But still I am not getting why every first string gets always initialised to an integer
>> with a value of 170 and then others follow as sequentially

170 is simply the location of where that first string is stored.  170 just happens to be the first available slot in this particular case. it is not a special number.

int i = "Hello";

is not good practice but what is happening here is that a string literal ("Hello") is used to initialize the integer i.  in the context of an expression, a string literal is converted by the compiler to a pointer to/address of/location of the string literal.in memory which in this case happens to be 170.  the others follow immediately after because.. well its a good place to put them, side by side.  it's compact.

>> and also why different platforms are behaving so differently to this.

the other platforms/compilers are not behaving differently.  the same thing is happening. the only difference is that you're generating 16 bit code as mokule pointed out, so the values appear different but the same thing is happening.

the first results i posted seemed scattered because your sample code was surrounded by a whole lot of other code that i was working on... =)..

b.
Hi Booki,
       seems my 3rd post came before ur 5th post.
Avik.
ASKER CERTIFIED SOLUTION
Avatar of booki
booki

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Are you asking why it is starting from 170 whenever you run or is it something else!?
Just to get some different results, I tried. Please correct me if I have some misconceptions here.

#include<stdio.h>
void main()
{
 int * i="Hello",*j,*k,*l;
 char * a;
 clrscr();
 a="";
 j=a;k=&j,l=&a;
 printf("i=%u  j=%u  k=%u l=%u",i,j,k,l);
 getch();
}
output is i=170 j=176 k=65520 l=65514

if i and j are offset values what is k then. Although i and j points to memory address of the string literals "Hello" and "" and k points to address of j and l points to the address of a. How can we account for this. Please clear my misconception. I have little knowledge about this.

Avik.
Avik77,

K and L hold offsets for the location of J and A, both of which are on the stack.  The stack grows down from high to low so the 'bottom' of the stack would be at offset 65535 (the maximum 16 bit value).

Notice that:
    - both J and A are very close to the bottom of the stack
    - J is closer to the bottom than A.
    - J and A are 6 bytes apart.  since one pointer is only 2 bytes there is a gap
      of 4 bytes in between.  just enough room for K and L.  the compiler has placed
      your variables on the stack in declaration order.

b.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

So they are offsets to the stack segment and the location of the string literals are the offset to the data segment. Since stack grows from high to low we get large values of offsets, but for const string literals it starts from the top. Are they the same segment i.e. SS=DS. I have this much to know .

Avik.