Avik Dasgupta
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.
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.
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.
>> 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.
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
"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.
>> 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.
>> (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.
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.
ASKER
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.
#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.
ASKER
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.
>> 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.
ASKER
Hi Booki,
seems my 3rd post came before ur 5th post.
Avik.
seems my 3rd post came before ur 5th post.
Avik.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Are you asking why it is starting from 170 whenever you run or is it something else!?
ASKER
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.
#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.
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.
ASKER
output was i=170 j=176