Re: is there a way to do this...
- From: Lew Pitcher <Lew.Pitcher@xxxxxx>
- Date: Fri, 02 Sep 2005 10:06:15 -0400
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Marc Boyer wrote:
> Le 02-09-2005, Steffen <s.weinstock@xxxxxx> a écrit :
>
>>sumit1680@xxxxxxxxxxxxxx wrote:
>>
>>>given below is a code snippet...
>>>
>>>void main()
>>>{
>>>int i=5;
>>>change(&i);
>>>i=6;
>>>printf("%d",i); //it should print 23 instead of 6
>>>}
>>>
>>>void change( int *i)
>>>{
>>>*i=23;
>>>//write some code here so that output of printf in main will be 23 not
>>>6
>>>}
>>>
>>>is this possible in C?
>>
>>void change(int* i)
>>{
>> *i = 23;
>>
>> void* ptr = &i;
>> ptr -= 4;
>> *((int*)ptr) += 10;
>>}
>>
>>works on x86, but it's a dirty, non-portable hack rather than C ...
>
>
> What are you trying to do there ? Could you give me
> some explanation ? Something like:
> void change(int* i){
> *i= 23;
> char* ptr= (char*) &i;
> ptr-= sizeof(int);
> int* int_ptr= (int*) ptr;
> *ptr+= 10;
> }
OK, here's what this piece of code does.
First off, remember that C fuction arguments are passed by value. This
piece of code makes some assumptions about the structure of the memory
around the value passed into the change() function, and it's
relationship to code in the main() function.
> void change(int* i){
i is a pointer to int, and on this platform, consumes a place in a
structure called a stack.
> *i= 23;
This statement sets the value of the storage pointed to by i to 23.
This is equivalent to the effects of a statement "i = 23;" in main()
> char* ptr= (char*) &i;
First off, this can only legally be done in C99. Previous versions of
the C standard would call this a syntax error, as declarations cannot
follow statements, and there has already been one statement.
This defines ptr to be a pointer to characters, which points to the
location of the /argument/ on the "stack". We now know where the value
is stored for the "pass by value" argument to change()
> ptr-= sizeof(int);
This decrements the pointer by the size of 1 integer. On a specific
platform, this "backs up" the pointer so that it now points to an
architectural artifact of this compiler/platform. Under certain
circumstances, the artifact that ptr now points to is the 'return
address' in main() to where a "return;" statement in change() will go
to.
> int* int_ptr= (int*) ptr;
First off, this can only legally be done in C99. Previous versions of
the C standard would call this a syntax error, as declarations cannot
follow statements, and there has already been one statement.
This defines int_ptr which is a pointer to int, and points to the same
location that ptr points to. Presumably this is still the 'return
address'
> *ptr+= 10;
This increments the 'return address' by 10 chars. Presumably, this
will change the 'return address' such that the termination of change()
will now skip the machine instructions in main() that implement the
"i=6;" statement
> }
And back we go to main(), presumably to a point 10 chars past where
the compiler intended us to go. If all the factors are correct, we've
just implicitly jumped past the "i=6;" statement in main(), and the
value of i set by change() will not have been changed.
> By the way, on my linux/x86/gcc, the output is 134513642, not
> 23...
That's because this is a non-portable, compiler-dependant,
platform-dependant, processor-dependant solution, and you don't have the
same compiler/platform/processor combination as the OP.
The OPs solution depends on
- - arguments being passed in a "stack" structure
- - a specific arrangement of hidden architectural elements on the stack
(i.e. the return address being stored immediately adjacent to the
arguments)
- - a specific size for one of the hidden architectural elements
- - a specific number of machine instruction bytes being generated
for a specific C statement
- - no compiler tricks like branch optimization, storage optimization, or
other internal arrangements that could intervene dynamically in the
code path that he is trying to skip
In other words, a completely platform-specific implementation.
> Marc Boyer
- --
Lew Pitcher, IT Specialist, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group
(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)
iD8DBQFDGFxWagVFX4UWr64RAhp/AJ9T1+iG0OuKSKmMprLpy2jD5W3tGgCfe/zS
dbFwMaz6+GRo0hRQT3Vgj4s=
=njdq
-----END PGP SIGNATURE-----
.
- References:
- is there a way to do this...
- From: sumit1680
- Re: is there a way to do this...
- From: Steffen
- Re: is there a way to do this...
- From: Marc Boyer
- is there a way to do this...
- Prev by Date: Re: is there a way to do this...
- Next by Date: Re: is there a way to do this...
- Previous by thread: Re: is there a way to do this...
- Next by thread: Re: is there a way to do this...
- Index(es):
Relevant Pages
|