String reversing problem

T

tmp123

Hi,

See inlines

Kind regards.

tmp123 said:
Oh wow, tested it and it does work. I've always thought that "start of
block" refers to the start of the function. Learn something new
everyday. This is indeed nice as localising scope is usually a "good
thing"(tm).


"works" only "more or less". Imagine you have a function with two big
locals.The first one is used at the start of function, the second one
at the end. You can thing this version saves stack space:

void test ( void )
{
{
char tmp1[10000];
... some code
}
{
char tmp2[10000];
... more code
}
}

However, if you display the address of tmp1 and tmp2, you will see that
lots of compilers converts it to:
void test ( void )
{
char tmp1[10000];
char tmp2[10000];
... some code
... more code
}

At the assembly level maybe but at the "C" level not true. Try
compiling:

#include <stdio.h>
int main()
{
int i;
for (i=0;i<10;i++) {
int n = i * 2;
printf("%d\n", n);
}
n = 3;
printf("%d\n", n);
}

and you'll get:

testprog.c: In function `main':
testprog.c:14: error: `n' undeclared (first use in this function)
testprog.c:14: error: (Each undeclared identifier is reported only once
testprog.c:14: error: for each function it appears in.)

Thanks for showing the difference between variable scope, visibility,
life... . It can be interesting for some readers.
Localising scope has little to do with trying to save memory but have
more to do with protecting variables from being misused. Think of the
difference of local and global, only in this case we get to use
variables that are more 'local' than local (if you know what I mean).

See this function:

/* swap pairs of characters in strings: 12345 => 21435 */
void reverse ( char *s )
{
/* end condition */
if ( s[0]=='\0' || s[1]=='\0' ) return;

/* swap values */
{
char tmp;
tmp=s[0];
s[0]=s[1];
s[1]=tmp;
}

reverse(s+2);
}

The first language I encountered this feature is in Perl. Little did I
know that C had it all along.

There are older languages than perl with it.

Kind regards.
 
E

Emmanuel Delahaye

tmp123 a écrit :
And taken into account that this piece of code has been presented as
"the good one" in a real programming team, some comments about:




1) It is not the same initialize a variable as give a variable the
first value it will take.

The effect is similar. What exactly is your point ?
2) Not always a stack to add variables is available,

Correct, but a C implementation requires automatic memory space for the
purpose. If there is no automatic memory available, the implementation
is not compliant.
or to add more
variables to it. Sometimes only modify code is allowed (i.e: patching
firmware in real time systems without stop them).

Sounds to be a twisted way of thinking...
3) Relation between names "i" and "j" and their meaning/usage is
totally lost.

Ok, I could have used ir and iw instead (standing for read/write indexes).
4) Never heard about "for" statement?. It is used to enclose in an easy
to read statement all control of the loop iterators (initializations,
exit condition and state update).

It's debatable. I personally prefer to use the for() constructs for
'canonic' loops

for (i = 0; i < n; i++)

For other usages (like the one here), I find while() more appropriate,
specially at debug stage.
{
char tmp = s ;



5) Declare char here, far of the semantically parent of it (char *s) it
is only a way to hide things. And lots of compilers will ignore it (no
new frame).


I failed to understand your point. What exactly is wrong here ? All I
could say is that I should have used int instead of char.
s = s [j];
s [j] = tmp;



6) It seems this code must always be compiled with latest version of
advanced compilers. The responsability to convert array index
calculations to pointer operations, even integers to pointers, is
transferred to compiler.


So what ? It seems that you are having hard time to find a real failiure
in Christian's code. Never mind, making a fool of yourself in public was
definitely your choice.
 
E

Emmanuel Delahaye

tmp123 a écrit :
"works" only "more or less". Imagine you have a function with two big
locals.The first one is used at the start of function, the second one
at the end. You can thing this version saves stack space:

void test ( void )
{
{
char tmp1[10000];
... some code
}
{
char tmp2[10000];
... more code
}
}

However, if you display the address of tmp1 and tmp2, you will see that
lots of compilers converts it to:
void test ( void )
{
char tmp1[10000];
char tmp2[10000];
... some code
... more code
}

that is not the expected one. That doesn't means this resource must not
be used. But it is good to known what will happen.

This is completely a compiler issue. The C language semantics allows the
optimization, but the implementors are free to optimize or not.
 
T

tmp123

Emmanuel said:
tmp123 a écrit :[...]
2) Not always a stack to add variables is available,

Correct, but a C implementation requires automatic memory space for the
purpose. If there is no automatic memory available, the implementation
is not compliant.
or to add more
variables to it. Sometimes only modify code is allowed (i.e: patching
firmware in real time systems without stop them).

Sounds to be a twisted way of thinking...

No, it sounds like a real situation. Imagine you have a lot of machines
controling some public service of your country. Imagine these machines
have one process with lots of threads, each one controlling one user
session. Now, ops, you find an error on code: two variables must be
swap.

What you do? Stop all country? Update a few code is easy, but better
not to change in a live system the stack structure. Thus, use a trick
like a^=b^... could be the difference between a big problem and a
critical problem.

Moreover, in the previous post there was a lot of person saying "to
swap you need a local variable". Well, like it is explained in the
first level of any good programming course, there are more options.
Ok, I could have used ir and iw instead (standing for read/write indexes).

They are perfectly logical names... taking into account we are talking
about a swap of data!
It's debatable. I personally prefer to use the for() constructs for
'canonic' loops

for (i = 0; i < n; i++)

For other usages (like the one here), I find while() more appropriate,

It seems you know more than the authors of C. Why not remove the "for"
specially at debug stage.

And after debug you modify code?
So what ? It seems that you are having hard time to find a real failiure
in Christian's code. Never mind, making a fool of yourself in public was
definitely your choice.

But never ignorant.

Kind regards.
 
F

Flash Gordon

tmp123 said:
Emmanuel said:
tmp123 a écrit :
[...]
2) Not always a stack to add variables is available,
Correct, but a C implementation requires automatic memory space for the
purpose. If there is no automatic memory available, the implementation
is not compliant.
or to add more
variables to it. Sometimes only modify code is allowed (i.e: patching
firmware in real time systems without stop them).
Sounds to be a twisted way of thinking...

No, it sounds like a real situation. Imagine you have a lot of machines
controling some public service of your country. Imagine these machines
have one process with lots of threads, each one controlling one user
session. Now, ops, you find an error on code: two variables must be
swap.

How often do you come across a bug where the correct action is just to
swap to variables? I've come across lots of bugs but can't think of a
time when it was a bug significant to require a live patch where that
would solve it.
What you do? Stop all country? Update a few code is easy, but better
not to change in a live system the stack structure. Thus, use a trick
like a^=b^... could be the difference between a big problem and a
critical problem.

So how are you going to actually change the code on this running system
without breaking it? Especially as it is highly unlikely to be in a
place where you have left a load of noops in that you can just
overwrite. If there are, then you can just read one, push it on the
stack, move the other, and pop the one you save off and write it back.
I've yet to come across any situation when that would not be acceptable.
Mind you, as I say, the chances of you being able to patch the code for
for that on a live system are negligible.

BTW, I have been involved in patching live systems, but it was where we
knew there was the possibility of needing to patch things and we could
design things in such a way as to specifically allow it. It also
required working at the assembler level rather than in C, and I can't
see how the tricks we applied could be used at the C level.
Moreover, in the previous post there was a lot of person saying "to
swap you need a local variable". Well, like it is explained in the
first level of any good programming course, there are more options.

In assembler programming it might sometimes make sense to use another
method, I've yet to see an instance where it would have made sense in
any higher level language, including in C.

It seems you know more than the authors of C. Why not remove the "for"
syntax and change it to "for <lv> = 1 TO <expr>". It is preferable for
you?.

Because then you could not do a list traversal for loop possibly.
Anyway, since no one uses every facility of any language, it should
harldy be a surprise when someone says they would not use a particular
facility in some specific way.
And after debug you modify code?

I doubt he would.
But never ignorant.

Actually, you do sound ignorant. Whether you are or not is a completely
different matter.
 
K

Keith Thompson

tmp123 said:
Emmanuel said:
tmp123 a écrit : [...]
or to add more
variables to it. Sometimes only modify code is allowed (i.e: patching
firmware in real time systems without stop them).

Sounds to be a twisted way of thinking...

No, it sounds like a real situation. Imagine you have a lot of machines
controling some public service of your country. Imagine these machines
have one process with lots of threads, each one controlling one user
session. Now, ops, you find an error on code: two variables must be
swap.

What you do? Stop all country? Update a few code is easy, but better
not to change in a live system the stack structure. Thus, use a trick
like a^=b^... could be the difference between a big problem and a
critical problem.

I can imagine the need to patch live code under some circumstances,
but doing so is not C programming.

It's conceivable, I suppose, that in the process of doing so you might
need to use the xor trick to swap two variables, but it hardly seems
likely.
Moreover, in the previous post there was a lot of person saying "to
swap you need a local variable". Well, like it is explained in the
first level of any good programming course, there are more options.

Sure, there are more options, but no better ones. The dangers of the
xor trick are explained in the C FAQ. Some CPUs may have swap
instructions, but there's no direct way to use them from C (though a
decent optimizing compiler should be able to generate one from the
obvious code).

The way to swap two variables in C is:
temp = x;
x = y;
y = x;
If you feel the need to use some other method, you should explain why
the obvious technique won't work for you.

[...]
But never ignorant.

Never? I find that difficult to believe. My own areas of ignorance
are vast (though I try to acknowledge them); I would expect the same
of any finite being.
 
P

pete

Albert said:
char s[5];

s[0] = 'h';
s[1] = 'e';
s[2] = 'l';
s[3] = 'l';
s[4] = 'o';

That's not a string.

/* BEGIN new.c */

#include <stdio.h>
#include <string.h>

char *str_rev(char *s);

int main(void)
{
char s[] = "hello";

puts(str_rev(s));
return 0;
}

char *str_rev(char *s)
{
char *t, swap;
char *const p = s;

if (*s != '\0') {
t = s + strlen(s + 1);
while (t > s) {
swap = *t;
*t-- = *s;
*s++ = swap;
}
}
return p;
}

/* END new.c */
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top