return in conditon - why not?

E

exander77

I am quite new to c++, about half of a year.
I juct wonder, why such code is not possible:

int chlen(char * ar) {
for(int i=0;ar||return i;i++);
}

In my opinion, it would be much "cuter" than this:

int chlen(char * ar) {
int i;
for(i=0;ar;i++);
return i;
}

Is there a reason, why return cound't be used as part of condition
(with true result, but interruptiong the function/program, so it is
not important).

eXander
 
L

Lance Diduck

I am quite new to c++, about half of a year.
I juct wonder, why such code is not possible:

int chlen(char * ar) {
  for(int i=0;ar||return i;i++);

}

In my opinion, it would be much "cuter" than this:

int chlen(char * ar) {
    int i;
    for(i=0;ar;i++);
    return i;

}

Is there a reason, why return cound't be used as part of condition
(with true result, but interruptiong the function/program, so it is
not important).

eXander


The short answer: because "return i" is not an expression that can be
evaluated.
The long answer: If it were, then one may presume that the evaluation
of "return i" is just i, and then this result is tested, i.e.

ar||return i
is really
(ar!=0)||((return i)!=0)
so for a an array ar that was length 3 (for instance)
ar[3]!=0 is false, but i!=0 is true
then "return i" is evaluated, resulting in "3"
"3" is not 0, so

ar||return i
is true
and the loop continues.

In C "return" is shorthand for the assembly routine "ret" (on intel
anyway) which is quite a complex instruction, not at all like "test a
value"

But I can see where you are coming from, which is a very Perl-ish
approach to expression evaluation.

Lance
 
C

Christopher

I am quite new to c++, about half of a year.
I juct wonder, why such code is not possible:

int chlen(char * ar) {
for(int i=0;ar||return i;i++);

}

In my opinion, it would be much "cuter" than this:

int chlen(char * ar) {
int i;
for(i=0;ar;i++);
return i;

}

Is there a reason, why return cound't be used as part of condition
(with true result, but interruptiong the function/program, so it is
not important).

eXander


What boolean value are you expecting "return i"; to evaluate to?
Are you wanting every iteration to return, since the condition is
evaluated every iteration?
If so, how is it that you are iterating at all? It would instantly
return

You're "cute" version doesn't make much sense either.
what boolean value are you expecting ar to evaluate to?
what happens when i increments beyond the bounds of the array?
why iterate at all if there is no action to be taken?
are you just taking it for granted that someone will give you a c
style char array that is null terminated?
are you taking it for granted that the null character will indeed
evaluate to false?

I wouldn't recommend using c style char arrays anyway. If you want to
hold some text, use a std::string

std::string mytext = "This is some text";
int length = mytext.size();
 
D

Daniel T.

I am quite new to c++, about half of a year.
I juct wonder, why such code is not possible:

int chlen(char * ar) {
for(int i=0;ar||return i;i++);
}


Cute, "return i" wouldn't be evaluated unless ar were false (none of
the posts I read caught this little bit.

But that still leaves us with the question as to what "return i"
evaluates to. I guess you could argue that it doesn't evaluate to
anything, because it isn't a boolean... And that would be your answer.
:)
In my opinion, it would be much "cuter" than this:

int chlen(char * ar) {
int i;
for(i=0;ar;i++);
return i;
}


(I'm assuming these are merely examples, that you would just use
strlen(const char*) if you wanted to take the length of a
null-terminated char array.)

I would avoid the above like the plague, and re-write it if I saw it.
Give the loop a body, always.

int charlen( const char* ar ) {
int result = 0; // always initialize your variables!
while ( ar[result] != 0 ) // I like to be explicit
++result;
return result;
}
Is there a reason, why return cound't be used as part of condition
(with true result, but interruptiong the function/program, so it is
not important).

If the return statement is supposed to evaluate to true as you state
here, then what would happen with this code?

bool func() {
return false;
}

int main() {
while ( func() ) { }
}

what would this mean?

int main() {
bool b = return 0;
}

or this?

bool foobar() {
return return false;
}

Sounds like a can of worms to me... :)
 
J

Jack Klein

I am quite new to c++, about half of a year.
I juct wonder, why such code is not possible:

int chlen(char * ar) {
for(int i=0;ar||return i;i++);

}

In my opinion, it would be much "cuter" than this:

int chlen(char * ar) {
int i;
for(i=0;ar;i++);
return i;

}

Is there a reason, why return cound't be used as part of condition
(with true result, but interruptiong the function/program, so it is
not important).

eXander


What boolean value are you expecting "return i"; to evaluate to?
Are you wanting every iteration to return, since the condition is
evaluated every iteration?
If so, how is it that you are iterating at all? It would instantly
return

You're "cute" version doesn't make much sense either.
what boolean value are you expecting ar to evaluate to?
what happens when i increments beyond the bounds of the array?
why iterate at all if there is no action to be taken?
are you just taking it for granted that someone will give you a c
style char array that is null terminated?


Presumably he is defining a function to work with a C string, although
he did not specifically state that.
are you taking it for granted that the null character will indeed
evaluate to false?

Why are you questioning whether the null character evaluates to false?
C and C++ have guaranteed that it does for about 35 years now.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
E

exander77

I am glad for your responses.
ar||return i
is true
and the loop continues.


There will be no loop because return terminates the function.
In C "return" is shorthand for the assembly routine "ret" (on intel
anyway) which is quite a complex instruction, not at all like "test a
value"

I know it, but we are speaking about programming, not about how is ret
handeled by processor, but how is return handeled by c/c++ compiler.
 
E

exander77

What boolean value are you expecting "return i"; to evaluate to?
Are you wanting every iteration to return, since the condition is
evaluated every iteration?
If so, how is it that you are iterating at all? It would instantly
return

You're "cute" version doesn't make much sense either.
what boolean value are you expecting ar to evaluate to?
what happens when i increments beyond the bounds of the array?
why iterate at all if there is no action to be taken?
are you just taking it for granted that someone will give you a c
style char array that is null terminated?
are you taking it for granted that the null character will indeed
evaluate to false?

I wouldn't recommend using c style char arrays anyway. If you want to
hold some text, use a std::string

std::string mytext = "This is some text";
int length = mytext.size();


I don't want to disrespect you in any way, but are you even
programming in c/c++?
Firstly, like Daniel T. said, there will by no return happening every
iteration, because seconod part of || (or) condition is not evaluted
if the first part is true.
Secondly, like Jack Klein said, it's been tens of years since NULL is
false and not NULL is true.
Next, when I iterate out of bound of the array nothing happens,
strlen() does exactly the same thing.

If you don't believe me, try yourself... :

int chlen(char * ar) {
int i;
for(i=0;ar;i++);
return i;
}

int main(int argc, char** argv) {
char a[1] = {'a','b','c','d'};
cout << strlen(a);
cout << chlen(a);
return (0);
}

Both functions just go out of bounds.
int charlen( const char* ar ) {
int result = 0; // always initialize your variables!
while ( ar[result] != 0 ) // I like to be explicit
++result;
return result;
}

It is basicly the same code as code as mine, I even think it'll be
compiled to the same code.
If the return statement is supposed to evaluate to true as you state
here, then what would happen with this code?
bool func() {
return false;
}
int main() {
while ( func() ) { }

}

func() returns false, what is mysterios about it? it is diametrally
different thing, what function returns and what will be the result of
return, for example if we say, that return returns always true

bool func() {
bool result = return false;
}

Than function return false, but in the bool variable result will be
true... if we could use it.
what would this mean?
int main() {
bool b = return 0;
}

In variable b is true, but function returns 0, i don't really see your
point.
bool foobar() {
return return false;
}

Returns false, because right return will be evalueted before left. I
still don't see your point.

I would really here some thoughtful ideas. :)
 
G

Grizlyk

I just wonder, why such code is not possible:

int chlen(char * ar) {
  for(int i=0;ar||return i;i++);

}


And the following code is impossible also

int i=0;
double d=0;

(a<b)? i=1: d=.3;

because "operator ?:" and "operator ||" is not intended to separate
branches of ordinare code, as if/else does, but to do conditional
evaluation only.

There are differences between branches of ordinary code and branches
of evaluation. The returned value from "ar||return i" will be
expected by "for" and "for" will be unrolled like this:

//for:
{
int i=0;

next:
if( !( ar || return i ) ) break; //for

body:
{
}

i++;
goto next;
}

In fact, the code

if( ! ) break;

is not necessary for you, because you do not want complier testing the
result of the condition "ar||return i".

Maybe it is possible to make compiler, that will be able to guess your
will and select between

next:
if( !( ar || return i ) ) break; //for

and

next:
if( !ar ) return i; //for

but there is other way: remove the condition into appropriate place of
code:

for( int i=0; ; ++i )
{ if(!ar)return i; }

and in addition, it is a good habit
- to do not use operator[] if you are not going to make random access
to C-style array (or to class-container), because indexing requires
multiplication even for C-style arrays, and for class-conteiner can
call waste of time; for any case, semantically by default indexing is
stuff to make random access rather than serial iteration

// indexing
template<class T>
int f1(T *const ar)
{
for( int i=0; ; ++i )
{ if(!ar)return i; }
}

//increment
template<class T>
int f2(T *const ar)
{
T *ptr=ar;

for( int i=0; ; ++i, ++ptr )
{ if(!*ptr)return i; }
}

struct A
{
int a[100];
char b[23];
bool operator!();
};

//indexing
; EBX = i
@12:
;//use multiplication for C-style arrays
imul eax,ebx,424
lea edx,dword ptr [ebp-42400]
add eax,edx

test al,al
jne short @14
@15:
inc ebx
jmp short @12
@14:

//increment
// for C-style arrays
; EBX = ptr, ESI = i
@20:
test al,al
jne short @22
@23:
inc esi
;//use addition for C-style arrays
add ebx,424
jmp short @20
@22:

- to do not use posfix increment if you do no need copy of index
variable (or especially of class-iterator)

Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new
 
A

Andrey Tarasevich

> ...
> Is there a reason, why return cound't be used as part of condition
> (with true result, but interruptiong the function/program, so it is
> not important).
> ...

'return' in C and C++ makes a return statement, not "return expression". You
can't use it as a part of another expression. The reason... Well, it was that
way in C, so it is that way in C++. Although, it could probably be made into an
expression in C++ without breaking legacy code. Anyway, nobody probably thought
this was really necessary.

Note that in C++ there's another remotely similar thing - 'throw' - which
happens to be an expression. It is a 'void' expression, though, not a 'bool'
one. Yet you can easily use it as a subexpression in another expression though
with the help of ',' operator or '?:' operator.

// A completely artificial/meaningless example
void chlen(char* ar)
{
for(int i = 0; ar || (throw 0, false); i++);
}


In theory, something like this could've probably been done to 'return' as well
(i.e. make it a 'void' expression, not an 'bool' one with an artificial result).
But, once again, there's really not much need for that. (Although it would be
interesting to know what was the rationale behind making 'throw' an expression
instead of control statement).
 
E

Erik Wikström

What boolean value are you expecting "return i"; to evaluate to?
Are you wanting every iteration to return, since the condition is
evaluated every iteration?
If so, how is it that you are iterating at all? It would instantly
return

You're "cute" version doesn't make much sense either.
what boolean value are you expecting ar to evaluate to?
what happens when i increments beyond the bounds of the array?
why iterate at all if there is no action to be taken?
are you just taking it for granted that someone will give you a c
style char array that is null terminated?
are you taking it for granted that the null character will indeed
evaluate to false?

I wouldn't recommend using c style char arrays anyway. If you want to
hold some text, use a std::string

std::string mytext = "This is some text";
int length = mytext.size();


I don't want to disrespect you in any way, but are you even
programming in c/c++?


I certainly hope not, there is no such language as C/C++.
Next, when I iterate out of bound of the array nothing happens,
strlen() does exactly the same thing.

If you don't believe me, try yourself... :

int chlen(char * ar) {
int i;
for(i=0;ar;i++);
return i;
}

int main(int argc, char** argv) {
char a[1] = {'a','b','c','d'};
cout << strlen(a);
cout << chlen(a);
return (0);
}

Both functions just go out of bounds.


Actually you get undefined behaviour and the fact that your program does
not crash or something else bad happens is just luck.
 
D

Daniel T.

int charlen( const char* ar ) {
int result = 0; // always initialize your variables!
while ( ar[result] != 0 ) // I like to be explicit
++result;
return result;
}

It is basicly the same code as code as mine, I even think it'll be
compiled to the same code.

There is lots of different structures that would be "basically the same"
and lots of different structures that would be "compiled to the same
code". Some are more readable (by humans) than others. So, given any two
structures that are basically the same, but one is more readable than
the other, which should we choose?
 
D

Daniel T.

I know it, but we are speaking about programming, not about how is ret
handeled by processor, but how is return handeled by c/c++ compiler.

Well that's part of the rub. :) Ever wonder why C has the ?: operator
*and* the if statement? It's because way back when, there were CPUs with
specialized instruction sets that the compiler could use to optimize the
?: more than the if statement.

That's way there are increment and decrement operators as well. A lot of
the low level stuff maps directly onto particular assembly routines.
 
E

exander77

I just wonder, why such code is not possible:
int chlen(char * ar) {
for(int i=0;ar||return i;i++);


And the following code is impossible also

int i=0;
double d=0;

(a<b)? i=1: d=.3;

because "operator ?:" and "operator ||" is not intended to separate
branches of ordinare code, as if/else does, but to do conditional
evaluation only.

There are differences between branches of ordinary code and branches
of evaluation. The returned value from "ar||return i" will be
expected by "for" and "for" will be unrolled like this:

//for:
{
int i=0;

next:
if( !( ar || return i ) ) break; //for

body:
{

}

i++;
goto next;

}

In fact, the code

if( ! ) break;

is not necessary for you, because you do not want complier testing the
result of the condition "ar||return i".

Maybe it is possible to make compiler, that will be able to guess your
will and select between

next:
if( !( ar || return i ) ) break; //for

and

next:
if( !ar ) return i; //for

but there is other way: remove the condition into appropriate place of
code:

for( int i=0; ; ++i )
{ if(!ar)return i; }

and in addition, it is a good habit
- to do not use operator[] if you are not going to make random access
to C-style array (or to class-container), because indexing requires
multiplication even for C-style arrays, and for class-conteiner can
call waste of time; for any case, semantically by default indexing is
stuff to make random access rather than serial iteration

// indexing
template<class T>
int f1(T *const ar)
{
for( int i=0; ; ++i )
{ if(!ar)return i; }

}

//increment
template<class T>
int f2(T *const ar)
{
T *ptr=ar;

for( int i=0; ; ++i, ++ptr )
{ if(!*ptr)return i; }

}

struct A
{
int a[100];
char b[23];
bool operator!();

};

//indexing
; EBX = i
@12:
;//use multiplication for C-style arrays
imul eax,ebx,424
lea edx,dword ptr [ebp-42400]
add eax,edx

test al,al
jne short @14
@15:
inc ebx
jmp short @12
@14:

//increment
// for C-style arrays
; EBX = ptr, ESI = i
@20:
test al,al
jne short @22
@23:
inc esi
;//use addition for C-style arrays
add ebx,424
jmp short @20
@22:

- to do not use posfix increment if you do no need copy of index
variable (or especially of class-iterator)

Maksim A. Polyaninhttp://grizlyk1.narod.ru/cpp_new


Very thanks! I learn a lot from your post. I know litte about
assembler. I am going to look at your page.
 

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

Staff online

Members online

Forum statistics

Threads
474,183
Messages
2,570,968
Members
47,518
Latest member
TobiasAxf

Latest Threads

Top