what wrong in this code

M

mohangupta13

here is a code snippet which is a part of larger program . GCC shows
error as
invalid lvalue in assignment
as i have marked in the code.

char* replace_escape_sq(char * text_in){

int c;
char * text=text_in;
for(text; *text; text++){
c=*text;
if(*text=='&'){ //find the escape char and do the replacement
//&lt --------- <
if(*text+1=='l' && *text+2=='t' && *text+3=';'){
text+=3; /* ERROR */
c='>';
}

//&gt --------------- >
else if(*text+1=='g' && *text+2=='t' && *text+3=';'){
text+=3; /*ERROR */
c='<';
}

it am really not getting whats wrong in these assignments.
please help
Mohan
 
M

mohangupta13

i am really sorry people for this i just didn't see this stupid
mistake .....sorry for wasting your precious time

here is a code snippet which is a part of larger program . GCC shows
error as
invalid lvalue in assignment
as i have marked in the code.

char* replace_escape_sq(char * text_in){

int c;
char * text=text_in;
for(text; *text; text++){
c=*text;
if(*text=='&'){ //find the escape char and do the replacement
//&lt --------- <
if(*text+1=='l' && *text+2=='t' && *text+3=';'){

*text+3==';' should have == not a single '='
text+=3; /* ERROR */
c='>';
}

//&gt --------------- >
else if(*text+1=='g' && *text+2=='t' && *text+3=';'){
same as above
text+=3; /*ERROR */
c='<';
}

it am really not getting whats wrong in these assignments.
computers are always right its just our head that err.
please help
Mohan

Mohan
 
D

David RF

here is a code snippet which is a part of larger program . GCC shows
error as
invalid lvalue in assignment
as i have marked in the code.

char* replace_escape_sq(char * text_in){

 int c;
 char * text=text_in;
 for(text; *text; text++){
         c=*text;
        if(*text=='&'){ //find the escape char and do the replacement
          //&lt --------- <
             if(*text+1=='l' && *text+2=='t' && *text+3=';'){
                     text+=3;       /*    ERROR     */
                      c='>';
                      }

            //&gt --------------- >
           else if(*text+1=='g' && *text+2=='t' && *text+3=';'){
                      text+=3;              /*ERROR */
                      c='<';
                 }

it am really not getting whats wrong in these assignments.
please help

if(*text+1=='l' && *text+2=='t' && *text+3=';'){
*text+3=';' -> must be *text+3==';' -------------------^

text+=3; /* ERROR */ -> no error here, but look at <for
(text; *text; text++)> are you sure there was any valid char in
position text + 3? you can find a beautifull segmentation fault
instead, poor code, like my english :)
 
D

David RF

             if(*text+1=='l' && *text+2=='t' && *text+3=';'){
*text+3=';' -> must be *text+3==';' -------------------^

 text+=3;       /*    ERROR     */ -> no error here, but look at <for
(text; *text; text++)> are you sure there was any valid char in
position text + 3? you can find a beautifull segmentation fault
instead, poor code, like my english :)

ops, sorry,

if(*text+1=='l' && *text+2=='t' && *text+3==';'){

text += 3 point to valid char
 
M

mohangupta13

ops, sorry,

if(*text+1=='l' && *text+2=='t' && *text+3==';'){

text += 3 point to valid char
i also first thought when i wrote it as poor code but the property of
&& makes it fine, so no problem of segmentation fault as i see.
Mohan
 
B

Ben Bacarisse

mohangupta13 said:
i am really sorry people for this i just didn't see this stupid
mistake .....sorry for wasting your precious time



*text+3==';' should have == not a single '='

I doubt that is the only problem. On most systems for *test + 1 ==
'l' to be true, *text must be 'k'. It is not possible for all three
tests to be true on any system I know (it would require 'l', 't' and
';' to be consecutive characters in the code used).

You almost certainly mean *(text + 1) which is more often written
text[1]. I.e:

if (text[1] == 'l' && text[2] == 't' && text[3] == ';')

but I would write:

if (strncmp(text + 1, "lt;", 3) == 0)

or maybe even:

if (strncmp(text, "&lt;", 4) == 0)
 
M

mohangupta13

mohangupta13 said:
i am really sorry people for this i just didn't see this stupid
mistake .....sorry for wasting your precious time
*text+3==';' should have == not a single '='

I doubt that is the only problem. On most systems for *test + 1 ==
'l' to be true, *text must be 'k'. It is not possible for all three
tests to be true on any system I know (it would require 'l', 't' and
';' to be consecutive characters in the code used).

You almost certainly mean *(text + 1) which is more often written
text[1]. I.e:
isn't text[1] = *(text+1) = *text +1

as + has higher precedence than * .
if (text[1] == 'l' && text[2] == 't' && text[3] == ';')

but I would write:
if (strncmp(text + 1, "lt;", 3) == 0)

or maybe even:

if (strncmp(text, "&lt;", 4) == 0)

but this requires certainty that text is at least 4 characters wide ,
but the previous code can just break out of the loop if not so by the
feature of && and i think ( i am not sure) it must be efficient as
compared to call to a function such as strncmp which if implemented as
a function requires stack frame set up and other overheads.
 
M

mohangupta13

I doubt that is the only problem. On most systems for *test + 1 ==
'l' to be true, *text must be 'k'. It is not possible for all three
tests to be true on any system I know (it would require 'l', 't' and
';' to be consecutive characters in the code used).
You almost certainly mean *(text + 1) which is more often written
text[1]. I.e:

isn't text[1] = *(text+1) = *text +1

as + has higher precedence than * .

I am really sorry .precedence of * is greater than + so *text +1 means
*(text)+1 rather than *(text+1)...really sorry
if (text[1] == 'l' && text[2] == 't' && text[3] == ';')
but I would write:
if (strncmp(text + 1, "lt;", 3) == 0)
or maybe even:
if (strncmp(text, "&lt;", 4) == 0)

but this requires certainty that text is at least 4 characters wide ,
but the previous code can just break out of the loop if not so by the
feature of && and i think ( i am not sure) it must be efficient as
compared to call to a function such as strncmp which if implemented as
a function requires stack frame set up and other overheads.


 
F

Flash Gordon

mohangupta13 said:
mohangupta13 said:
i am really sorry people for this i just didn't see this stupid
mistake .....sorry for wasting your precious time
here is a code snippet which is a part of larger program . GCC shows
error as
invalid lvalue in assignment
as i have marked in the code.
char* replace_escape_sq(char * text_in){
int c;
char * text=text_in;
for(text; *text; text++){
c=*text;
if(*text=='&'){ //find the escape char and do the replacement
//&lt --------- <
if(*text+1=='l' && *text+2=='t' && *text+3=';'){
*text+3==';' should have == not a single '='
I doubt that is the only problem. On most systems for *test + 1 ==
'l' to be true, *text must be 'k'. It is not possible for all three
tests to be true on any system I know (it would require 'l', 't' and
';' to be consecutive characters in the code used).

You almost certainly mean *(text + 1) which is more often written
text[1]. I.e:
isn't text[1] = *(text+1) = *text +1

as + has higher precedence than * .

No, your equivilance is wrong. *text + 1 is equivilent to (*text) + 1
if (text[1] == 'l' && text[2] == 't' && text[3] == ';')

but I would write:
if (strncmp(text + 1, "lt;", 3) == 0)

or maybe even:

if (strncmp(text, "&lt;", 4) == 0)

but this requires certainty that text is at least 4 characters wide ,

No it doesn't. strncmp will terminate as soon as it reaches the end of
either string or when the number of characters has been reached.
but the previous code can just break out of the loop if not so by the
feature of && and i think ( i am not sure) it must be efficient as
compared to call to a function such as strncmp which if implemented as
a function requires stack frame set up and other overheads.

<snip>

strncmp is often inlined by the compiler avoiding the overheads of a
call and can also sometimes use various strange and wonderful tricks to
improve performance even more. Of course, you might have to tell your
compiler to optimise the code for this to happen, but that is normally
easy to do.
 
F

Flash Gordon

Kenneth said:
Flash said:
No it doesn't. strncmp will terminate as soon as it reaches the end of
either string or when the number of characters has been reached.
[...]

Won't str[n]cmp() also stop at the first mismatch?

I was about to say that it would, but what I looked there is no such
guarantee even though the return value is determined by the first
difference (if there is one). There is a guarantee, however, that
characters after the first 0 will not be compared.
Is the following well-behaved?

#include <string.h>
char *LastByteOfMemory = "a";
int IsThisDefined(void)
{
return( strcmp(LastByteOfMemory,"foo") );
}

Through some magic, the "a" to which LastByteOfMemory points is in the
last byte of addressable memory. Will strcmp() ever attempt to access
anything beyond LastByteOfMemory[0], given that 'a'!='f' ?

That strcmp is well defined. It would also be well defined if you used
strncmp with a last parameters of 1000. However, this, I believe, is
undefined.

char nonstr[2] = "12";
char str = "AAA";
strncmp(str,nonstr,3);
 
F

Flash Gordon

Kenneth said:
Flash said:
Kenneth Brody wrote: [...]
Is the following well-behaved?

#include <string.h>
char *LastByteOfMemory = "a";
int IsThisDefined(void)
{
return( strcmp(LastByteOfMemory,"foo") );
}

Through some magic, the "a" to which LastByteOfMemory points is in
the last byte of addressable memory. Will strcmp() ever attempt to
access anything beyond LastByteOfMemory[0], given that 'a'!='f' ?

That strcmp is well defined. It would also be well defined if you used
strncmp with a last parameters of 1000. However, this, I believe, is
undefined.

char nonstr[2] = "12";
char str = "AAA";
strncmp(str,nonstr,3);

Oops. I meant to have:

char LastByteOfMemory[1] = "a";

or

char *LastByteOfMemory = { 'a' } ;

(Or, at least imply that the 'a' was the last byte of memory, without a
terminating '\0'.)

I would say undefined because the standard specifies pointers to strings
(which means they must have a '\0'terminator) and does not say it stops
before it reaches the end of one of the strings.
 
K

Keith Thompson

Flash Gordon said:
Kenneth said:
Flash said:
Kenneth Brody wrote: [...]
Is the following well-behaved?

#include <string.h>
char *LastByteOfMemory = "a";
int IsThisDefined(void)
{
return( strcmp(LastByteOfMemory,"foo") );
}

Through some magic, the "a" to which LastByteOfMemory points is in
the last byte of addressable memory. Will strcmp() ever attempt
to access anything beyond LastByteOfMemory[0], given that 'a'!='f'
?

That strcmp is well defined. It would also be well defined if you
used strncmp with a last parameters of 1000. However, this, I
believe, is undefined.

char nonstr[2] = "12";
char str = "AAA";
strncmp(str,nonstr,3);

Oops. I meant to have:

char LastByteOfMemory[1] = "a";

or

char *LastByteOfMemory = { 'a' } ;

(Or, at least imply that the 'a' was the last byte of memory,
without a terminating '\0'.)

I would say undefined because the standard specifies pointers to
strings (which means they must have a '\0'terminator) and does not say
it stops before it reaches the end of one of the strings.

No, the standard *doesn't* specify pointers to strings for strncmp,
though it does for strcmp. See C99 7.21.4.4:

Description
The strncmp function compares not more than n characters
(characters that follow a null character are not compared) from
the array pointed to by s1 to the array pointed to by s2.

Returns
The strncmp function returns an integer greater than, equal to, or
less than zero, accordingly as the possibly null-terminated array
pointed to by s1 is greater than, equal to, or less than the
possibly null-terminated array pointed to by s2

C90 had different wording, but also didn't require pointers to
strings.

Note, however, that it doesn't guarantee that it stops comparing
when it sees a mismatch. In the case above, where the count is
3 and one of the arrays is only 2 characters long, the behavior
is still undefined -- even though an implementation easily could
return a result after looking at only the first character.
 
F

Flash Gordon

Keith said:
Flash Gordon said:
Kenneth said:
Flash Gordon wrote:
Kenneth Brody wrote:
[...]
Is the following well-behaved?

#include <string.h>
char *LastByteOfMemory = "a";
int IsThisDefined(void)
{
return( strcmp(LastByteOfMemory,"foo") );
}

Through some magic, the "a" to which LastByteOfMemory points is in
the last byte of addressable memory. Will strcmp() ever attempt
to access anything beyond LastByteOfMemory[0], given that 'a'!='f'
?
That strcmp is well defined. It would also be well defined if you
used strncmp with a last parameters of 1000. However, this, I
believe, is undefined.

char nonstr[2] = "12";
char str = "AAA";
strncmp(str,nonstr,3);
Oops. I meant to have:

char LastByteOfMemory[1] = "a";

or

char *LastByteOfMemory = { 'a' } ;

(Or, at least imply that the 'a' was the last byte of memory,
without a terminating '\0'.)
I would say undefined because the standard specifies pointers to
strings (which means they must have a '\0'terminator) and does not say
it stops before it reaches the end of one of the strings.

No, the standard *doesn't* specify pointers to strings for strncmp,
though it does for strcmp. See C99 7.21.4.4:

The example code by Kenneth above uses strcmp. I assumed that the
incorrection[1] he posted was to his code using strcmp not to my example
using strncmp.

Note, however, that it doesn't guarantee that it stops comparing
when it sees a mismatch. In the case above, where the count is
3 and one of the arrays is only 2 characters long, the behavior
is still undefined -- even though an implementation easily could
return a result after looking at only the first character.

I had not quoted the standard, but I had said I believed this to be the
case when talking about strncmp above.

[1] It is an incorrection rather than a correction because it is
deliberately adding an error!
 
P

Phil Carmody

Kenneth Brody said:
Flash Gordon wrote:
[...]
The example code by Kenneth above uses strcmp. I assumed that the
incorrection[1] he posted was to his code using strcmp not to my
example using strncmp. [...]
[1] It is an incorrection rather than a correction because it is
deliberately adding an error!

I guess it basically comes down to "the standard doesn't guarantee
that strncmp() and friends won't read beyond the first mismatch, and
therefore could (attempt to) access memory beyond the end of one of
the buffers, even with a mismatch before that end". It may make sense
on some platforms to do so, if it's more efficient than checking every
byte individually and stopping at a mismatch. (Perhaps even a simple
"c = *ptr++;", where the incremented ptr results in a trap
representation at the end of memory.)

If ptr may be validly dereferenced, then it points to an object.
Therefore the address ptr+1 is valid as an address, and not a trap
representation.
Sometimes, what is intuitively "right" may not match reality.

Many times. Least surprises is one of the features I like most in a
language. (But 'sufficiently powerful' dominates.)

Phil
 

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

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,196
Latest member
ScottChare

Latest Threads

Top